首页 > 解决方案 > 如何在 vuex 中添加元素并且不开始计算值?

问题描述

我尝试在 vue/vyex 上添加分数,所有添加都发生在 getter 中,因此这意味着在我们更改某些字段后,我们开始计算值。

当我单击“添加新分数”按钮时,我创建具有计算属性的新对象并在 getter 中出错,因为我如何理解,计算检查更改和 getter 开始工作,但没有新属性,我接受错误 :Error in v-on handler: "TypeError: Cannot read property 'denominator' of undefined"

店铺

export default new Vuex.Store({
  state: {
    fractions: [
      {
        id: 1,
        numerator: 0,
        denominator: 0,
      },
      {
        id: 2,
        numerator: 0,
        denominator: 0,
      },
    ],
  },
  actions,
  mutations: {
    changeInput(state, payload) {
      state.fractions.forEach((el) => {
        if (el.id === payload.id) {
          el[payload.key] = payload[payload.key];
        }
      });
    },
    addFraction(state) {
      state.fractions.push({
        id: state.fractions.length + 1,
        numerator: 0,
        denominator: 0,
      });
    },
    deleteFraction(state, id) {
      state.fractions.forEach((el, i) => {
        if (el.id === id) {
          state.fractions.splice(i, 1);
        }
      });
    },
  },
  getters: {
    takeSum(state) {
      const sum = {
        denominator: 0,
        numerator: 0,
      };
      state.fractions.reduce((prev, curr) => {
        sum.denominator = prev.denominator + curr.denominator;
        sum.numerator = prev.numerator + curr.numerator;
      });

      return sum;
    },
  },

});

组件计算属性

 computed: {
    ...mapState([
      'fractions',
    ]),

    ...mapGetters([
      'takeSum',
    ]),

  },

和模板

<Fraction
            v-for="(fraction, index) in fractions"
            :key="index"
            :numerator=fraction.numerator
            :denominator=fraction.denominator
            :id="fraction.id"
            @changeFractionInput=changeFractionInput
            v-bind:onClick="deleteFraction"
    />
    <div>sum: {{takeSum}}</div>

标签: vue.jsvuex

解决方案


你的问题在takeSum. 您没有正确使用减速器。

reducer 遍历数组的每个元素,并从中计算单个值。这个值可以是任何东西,包括一个对象。但是,您必须在每个项目之间返回结果。您返回的将在下一个周期中使用。你的代码会变成这样:

  const sum = state.fractions.reduce((prev, curr) => {
    const newSum = { ...prev };

    newSum.denominator = prev.denominator + curr.denominator;
    newSum.numerator = prev.numerator + curr.numerator;

    return newSum;
  });

因为你没有返回任何东西,第一次reducer(里面的函数reduce(..)被调用,它是用你数组的第一个和第二个元素调用的。第二次调用它是用prevbeing undefined(你没有返回任何东西),而currbeing数组中的第三个元素。


但是,我必须说您没有正确计算分数的总和。如果我们取 1/2 和 1/3 的和,你会说这个和实际上是 2/5。然而,一个快速的计算告诉我们,情况并非如此。

如果要将两个分数相加,则必须确保两者的分母相等。对于我们之前的示例,这将是1/2 = 3/61/3 = 2/6,因此总和将是5/6。的典型总和a/b + c/d((a*d) + (b*c)) / (b*d)


推荐阅读