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

How to obtain children components inside Vue.js app

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

我希望能够在任何单元格更改时计算组件的总和。我想出了一种方法来存储单元格的所有值,方法是在传播更改事件时缓存它们。但是,这是最好的方法吗?有没有更好的动态抓取子项的方法?我知道 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];
        } 
      }
    }
  }
});

I understand props are the way to send data down, but how do I pull data up?

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

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

如上面 link 中所述,<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)。父组件(根)保持干净,您可以简单地使用计算的 属性 作为 subTotal.

但是如果你有一个简单的整数列表,比如 this.cells = [1,2,3,4] 并尝试使用 v-model 将值传递给单元格组件,这将不起作用。您将收到以下错误:

[Vue warn]: : You are binding v-model directly to a v-for iteration alias. This will not be able to modify the v-for source array because writing to the alias is like modifying a function local variable. Consider using an array of objects and use v-model on an object property instead.

如果您可以将 this.cells 修改为对象数组,那么您可以采用一种干净的方式来执行此操作,例如:

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

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