如何在Vue.js应用程序中获取子组件

时间:2016-12-14 03:06:44

标签: vue.js vuejs2

所以,我有一个包含多个子组件的应用程序。基本上是电子表格。

我希望能够在任何单元格更改时计算组件的总和。我发现了一种在传播更改事件时通过缓存来存储单元格的所有值的方法。但是,这是最好的方法吗?有没有更好的方法动态抓住孩子?我理解props是发送数据的方式,但我如何提取数据?

这是HTML:

<html>

<head>

</head>

<body>

<span id="calculator">
<template v-for="i in 5">
<cell v-bind:index="i" v-on:total="total"></cell>
</template>
{{ subtotal }}

{{ cells }}
</span>

<script src="vue.js"></script>
<script src="app.js"></script>

</body>

</html>

app.js:

Vue.component( 'cell', {
  template: "<input v-model='value' v-on:change='total' size='10' type='text'/>",
  props: {
    index: Number
  },
  data: function() {
      return {
        value: 0
      };
  },
  methods: {
    total: function() {
      console.log( "Value is now: " + this.value + " for index: " + this.index )
      this.$emit( 'total', this.value, this.index )
    }
  }
});

var app = new Vue( {
  data: {
    subtotal: 0,
    cells: []
  },
  el: "#calculator",
  methods: {
    total: function( value, indexPlusOne )  {
      var index = indexPlusOne-1;
      var v =  parseInt( value );
      Vue.set( this.cells, index, v);
      console.log( "Inside the total function: " + v + " " + index );
      this.subtotal = 0;
      for( var i = 0; i < this.cells.length; i++ ) {
        if( this.cells[i] ) {
          this.subtotal += this.cells[i];
        } 
      }
    }
  }
});

1 个答案:

答案 0 :(得分:2)

  

我理解道具是发送数据的方式,但我如何提取数据呢?

最好的方法是使用v-model为您的自定义cell组件提取数据。

参考:https://vuejs.org/v2/guide/components.html#Form-Input-Components-using-Custom-Events

正如上面的链接所解释的那样,<input v-model="something">是一个语法糖:

<input v-bind:value="something" v-on:input="something = $event.target.value">

所以,你理想的解决方案就像:

<cell v-model="item" v-for="item in all_cell_items"></cell>

在单元组件中,您可以通过以下方式将值传递回父(根)组件:this.$emit("input", newValue)。父组件(root)保持干净,您可以简单地使用subTotal的计算属性。

但如果您有一个简单的整数列表(例如this.cells = [1,2,3,4])并尝试使用v-model将值传递给单元组件,则无效。您将收到以下错误:

  

[Vue警告] ::您将v-model直接绑定到v-for迭代别名。这将无法修改v-for源数组,因为写入别名就像修改函数局部变量一样。考虑使用对象数组并在对象属性上使用v-model。

如果您可以将this.cells修改为对象数组,那么您可以采用干净的方式:

<cell v-model="item.price" :label="item.name" v-for="item in all_items"></cell>

这是一个适用于此示例的jsFiddle:https://jsfiddle.net/mani04/9b7n3qmt/