在vuejs app中调用两次计算函数

时间:2018-06-04 19:54:46

标签: 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>

这是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);
    }
  }
});

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

正如您所看到的,我只是实施的一部分。通过实施名为computed的{​​{1}}功能,我获得了产品系列总数。现在,我试图通过首先获得购物车中的产品数量(最终将乘以lineTotal常数)来获得运输线。我已经实现了shipping功能似乎可以完成这项工作,但我注意到现在有一​​个控制台错误:

totalItems

深入挖掘,似乎TypeError: Cannot read property 'reduce' of undefined 函数被调用了两次;第一次totalItemsthis.order.cartItems因此undefined来电错误。

为什么会这样?我可能会以错误的方式处理所有这些问题,因此我愿意接受如何向前推进的建议;我在学习曲线的最开始处:)

感谢。

1 个答案:

答案 0 :(得分: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"元素中使用tr,等待.shipping属性填充。