在vuejs应用中两次调用了计算函数

Dan*_*Dan 5 vuejs2

我正在通过实现一个简单的购物车来学习一些VueJS。

这是我的HTML:

<div id="app">
  <table>
    <thead>
      <tr>
        <th>Product</th>
        <th>Unit price</th>
        <th>Quantity</th>
        <th>Total</th>
      </tr>
    </thead>
    <tbody>
      <tr v-for="(cartItem, index) in order.cartItems">
        <td>{{ cartItem.productName }}</td>
        <td>{{ cartItem.unitPrice }}</td>
        <td>{{ cartItem.quantity }}</td>
        <td>{{ lineTotal[index] }}</td>
      </tr>
      <tr class="shipping">
        <td>Shipping</td>
        <td>{{ shipping }}</td>
        <td>{{ totalItems }}</td>
        <td></td>
      </tr>
    </tbody>
    <tfoot>
      <tr>
        <td colspan="3">TOTAL</td>
        <td></td>
      </tr>
    </tfoot>
  </table>
</div>
Run Code Online (Sandbox Code Playgroud)

这是JS:

const shipping = 1.5;

const app = new Vue({
  el: '#app',
  data: {
    shipping: shipping.toFixed(2),
    order: []
  },
  created() {
    fetch('https://api.myjson.com/bins/1fk6ua')
      .then(response => response.json())
      .then(json => {
      this.order = json.order
    })
  },
  computed: {
    lineTotal: function () {
      return this.order.cartItems.map(function (cartItem) {
        return (cartItem.unitPrice * cartItem.quantity).toFixed(2);
      });
    },
    totalItems: function(){
      return this.order.cartItems.reduce(function (totalItems, cartItem) {
        return totalItems + parseInt(cartItem.quantity);
      }, 0);
    }
  }
});
Run Code Online (Sandbox Code Playgroud)

这是一个小提琴:https : //jsfiddle.net/8fg70ud2/

如您所见,我只是实现过程的一部分。通过实现一个computed名为的功能,我已经使产品线的总和起作用lineTotal。现在,我想通过首先获取购物车中的产品数量(最终将乘以该shipping常数)来使运输线正常工作。我已经实现了totalItems似乎可以完成这项工作的功能,但我注意到现在出现了控制台错误:

TypeError: Cannot read property 'reduce' of undefined
Run Code Online (Sandbox Code Playgroud)

深入研究,似乎该totalItems函数被调用了两次;在第一时间this.order.cartItemsundefined因此reduce呼叫被示数。

为什么会这样呢?我很可能会以错误的方式处理所有这些问题,因此对于如何前进持开放态度。我正处于学习曲线的开始阶段:)

谢谢。

Pra*_*ant 5

创建Vue实例后,它具有order您初始化为的属性[]。在您v-for尝试获得的order.cartItems结果中也有结果,undefined但是您没有注意到那里的任何问题,因为Vue摆脱了在内部创建结构的麻烦,v-if从未碰到另一个计算属性lineTotal

但是,totalItems马上计算。与order仍然[]order.cartItemsundefined。显然没有reduce办法。因此,错误。

然后,在created回调中,您实际上获取了数据,并order使用实际对象填充了属性。由于order属性是计算属性的依赖项,并且属性totalItems已更新,因此Vue将再次计算该属性,并且该时间order属性具有正确的数据结构。而且,在第二轮中一切都会好起来的。

解决方案非常简单。等到order通过v-if="order.cartItems"在类的contains tr元素中填充属性为止.shipping