跟踪一系列组件

时间:2017-04-20 21:41:30

标签: vue.js

我有一个非常简单的Vue应用程序:

<div id="app">

  <item v-for="item in items" v-bind:title="item.title" v-bind:price="item.price"
        @added="updateTotal(item)"></item>

  <total v-bind:total="total"></total>

</div>

和一个Vue实例:

Vue.component('item',{
  'props' : ['title', 'price'],
  'template' : "<div class='item'><div>{{ title }} – ${{total}} </div><button class='button' @click='add'>Add</button></div>",
  'data' : function(){
    return {
      quantity : 0
    }
  },
  'computed' : {
    total : function(){
      return (this.quantity * this.price).toFixed(2);
    }
  },
  methods : {
    add : function(){
      this.quantity ++;
      this.$emit('added');
    }
  }
});

Vue.component('total', {
  'props' : ['total'],
  'template' : "<div class='total'>Total: ${{ total }}</div>",

});

var app = new Vue({
  'el' : '#app',
  'data' : {
    'total' : 0,
    'items': [
      {
        'title': 'Item 1',
        'price': 21
      }, {
        'title': 'Item 2',
        'price': 7
      }
    ],
  },
  methods : {
    'updateTotal' : function(item){
      console.log('updating');
      this.total += item.price;
    }
  }
});

演示链接: https://codepen.io/EightArmsHQ/pen/rmezQq?editors=1010

我想要做的是更新<total>组件,因为各种项目已添加到购物车中。我现在正在工作,但它似乎并不优雅。

现在,我将每个项目的价格加到总计中。我真正想要做的是将总数作为计算属性,然后每次更改项目组件时,循环遍历它们都添加每个的数量*价格。有没有办法可以做到这一点?

我刚刚提出的一个选项是将主应用中的updateTotal方法替换为以下方法:

methods : {
  'updateTotal' : function(item){
    item.quantity += 1;
  }
},
computed : {       total : function(){
    var t = 0;
    for(var i = 0; i < this.items.length; i ++){
      t += this.items[i].quantity * this.items[i].price;
    }
    return t;
  }
}

因此,开始将每个项目的数量存储在Vue应用程序中,而不是组件中。但是将每个项目的数量存储在自己的组件中更有意义......不是吗?处理此问题的最佳方法是什么?

1 个答案:

答案 0 :(得分:3)

也许与直觉相反,组件只需要他们的数据作为道具。项目(作为数据对象)在父项中定义;也可以在那里定义id name -- ---- 2 fi 4 fum 。然后在组件中使用这些数据项,但通过事件对父项进行更改。

使用包含数量的数组,可以轻松创建所需的计算总数。

quantity
Vue.component('item', {
  'props': ['item'],
  'template': "<div class='item'><div>{{ item.title }} – ${{total}} </div><button class='button' @click='add'>Add</button></div>",
  'computed': {
    total: function() {
      return (this.item.quantity * this.item.price).toFixed(2);
    }
  },
  methods: {
    add: function() {
      this.$emit('added');
    }
  }
});

Vue.component('total', {
  'props': ['total'],
  'template': "<div class='total'>Total: ${{ total }}</div>",

});

var app = new Vue({
  'el': '#app',
  'data': {
    'items': [{
      'title': 'Item 1',
      'price': 21,
      'quantity': 0
    }, {
      'title': 'Item 2',
      'price': 7,
      'quantity': 0
    }],
  },
  computed: {
    total() {
      return this.items.reduce((a, b) => a + (b.price * b.quantity), 0).toFixed(2);
    }
  },
  methods: {
    updateTotal(item) {
      ++item.quantity;
    }
  }
});