#javascript #vuejs2 #vuex #store #vuex-modules
Вопрос:
Например, у меня есть два списка: доход и результат. И у меня есть два хранилища (одно для дохода и одно для результата). Я добавляю эти хранилища в модулях в index.js.
Я могу создать одно хранилище для этих доходов и результатов, отобразить его в списке и рассчитать его. Но я хочу сделать отдельный магазин для каждого.
Теперь вопрос в следующем: как я могу это правильно реализовать? Я грубо так и сделал. Но здесь я показываю и рассчитываю только ДОХОД, и все.
Как это сделать лучше? импорт через …mapGetters двух хранилищ в одном компоненте для расчета и отображения в списке? Или возьмите данные из двух хранилищ и рассчитайте все в index.js. Затем возьмите эти данные из index.js? Как использовать несколько модулей в одном компоненте? Я хочу показать баланс доходов и результатов в одном компоненте и показать в списке.
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;
это мой компонент, в котором я рассчитываю баланс
<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>
Комментарии:
1. Почему бы вам просто не использовать
...mapGetters("outcome", ["outcomeList"])
и свой компонент тоже?
Ответ №1:
Вот вариант для более правильного использования магазина с модулями.
Я также помещаю расчет в геттер, что делает ваш компонент чистым. Постарайтесь привнести логику в магазин, чтобы вы могли использовать сумму баланса в любом месте.
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;
Это ваш компонент
<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>