For example, I have two lists: income and outcome. And I have two storages (one for income and one for outcome). I am adding these storages in modules into index.js.
I can make one repository for these income and outcome, display it in the list and calculate it. But I want to make a separate store for each.
Now the question is: How can I implement this correctly? I roughly did. But here I show and calculate only INCOME and that's it.
How to do it better? import via ...mapGetters two storages in one component to be calculate and show in the list? Or take data from two storages, and calculate everything in the index.js. Then take this data from the index.js? How do I use multiple modules in one component? I want to show the balance of income and outcome in one component and show in the list.
index.js
import Vue from "vue";
import Vuex from "vuex";
import income from "./modules/income";
import outcome from "./modules/outcome";
Vue.use(Vuex);
export default new Vuex.Store({
state: {},
mutations: {},
actions: {},
modules: {
income,
outcome,
},
});
income.js
import Vue from "vue";
const income = {
namespaced: true,
state: {
list: {
1: {
type: "INCOME",
value: 100,
comment: "Some comment",
id: 1,
},
},
},
getters: {
incomeList: ({ list }) => list,
},
mutations: {
},
actions: {
},
},
};
export default income;
outcome.js
// import Vue from "vue";
const outcome = {
namespaced: true,
state: {
list: {
1: {
type: "OUTCOME",
value: -50,
comment: "Some outcome comment",
id: 2,
},
},
},
getters: {
outcomeList: ({ list }) => list,
},
mutations: {
},
actions: {
},
};
export default outcome;
this is my component where i calculate balance
<template>
<div class="total-value" :style="balanceColor">
Balance: {{ totalBalance }}
</div>
</template>
<script>
import {mapGetters} from 'vuex';
export default {
name: 'TBalance',
computed: {
balanceColor: function() {
return {
color: this.totalBalance === 0 ? 'black' : this.totalBalance > 0 ? 'green' : 'red'
}
},
totalBalance() {
return Object.values(this.incomeList).reduce((acc, item) => acc + item.value, 0)
},
...mapGetters("income", ["incomeList"]),
},
methods: {
}
}
</script>
I also put the calculation in the getter, which makes your component clean. Try to bring the logic to the store so you can use the balance amount anywhere.
index.js
import Vue from "vue";
import Vuex from "vuex";
import income from "./modules/income";
import outcome from "./modules/outcome";
Vue.use(Vuex);
export default new Vuex.Store({
state: {},
mutations: {},
actions: {},
modules: {
income,
outcome,
},
});
income.js
const income = {
namespaced: true,
state: {
list: {
1: {
type: "INCOME",
value: 100,
comment: "Some comment",
id: 1,
},
},
},
getters: {
incomeBalance: state => {
// also, you can move this function into a separate file, and reuse
return Object.values(state.list).reduce((acc, item) => acc + item.value, 0);
},
},
};
export default income;
outcome.js
const outcome = {
namespaced: true,
state: {
list: {
1: {
type: "OUTCOME",
value: -50,
comment: "Some outcome comment",
id: 2,
},
},
},
getters: {
outcomeBalance: state => {
return Object.values(state.list).reduce((acc, item) => acc + item.value, 0);
},
},
};
export default outcome;
It is your component
<template>
<div class="total-value" :style="balanceColor">Balance: {{ incomeBalance }}</div>
</template>
<script>
import { mapGetters, mapState } from 'vuex';
export default {
name: 'TBalance',
computed: {
...mapState('outcome', ['list']), // if you want a list here i added for example
...mapState('income', ['list']), // if you want a list here i added for example
...mapGetters('outcome', ['outcomeBalance']), // also added it for example
...mapGetters('income', ['incomeBalance']),
balanceColor() {
return {
color: this.incomeBalance === 0 ? 'black' : this.incomeBalance > 0 ? 'green' : 'red',
};
},
},
methods: {},
};
</script>