如何在 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/
所以,我有一个包含多个子组件的应用程序。基本上是一个电子表格。
我希望能够在任何单元格更改时计算组件的总和。我想出了一种方法来存储单元格的所有值,方法是在传播更改事件时缓存它们。但是,这是最好的方法吗?有没有更好的动态抓取子项的方法?我知道 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/