Как разобраться в модулях в VUEX-МАГАЗИНЕ

#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>