语境
在 Vue 2.0 中,文档和其他文件清楚地表明从父到子的通信是通过 props 发生的。
问题
父母如何通过props告诉其孩子发生了事件?
我应该只看一个叫做事件的props吗?这感觉不对,替代方案也不对($emit
/$on
用于孩子到父母,而集线器模型用于遥远的元素)。
例子
我有一个父容器,它需要告诉它的子容器可以在 API 上进行某些操作。我需要能够触发功能。
在 Vue 2.0 中,文档和其他文件清楚地表明从父到子的通信是通过 props 发生的。
父母如何通过props告诉其孩子发生了事件?
我应该只看一个叫做事件的props吗?这感觉不对,替代方案也不对($emit
/$on
用于孩子到父母,而集线器模型用于遥远的元素)。
我有一个父容器,它需要告诉它的子容器可以在 API 上进行某些操作。我需要能够触发功能。
给子组件一个ref
,用来$refs
直接调用子组件上的一个方法。
html:
<div id="app">
<child-component ref="childComponent"></child-component>
<button @click="click">Click</button>
</div>
javascript:
var ChildComponent = {
template: '<div>{{value}}</div>',
data: function () {
return {
value: 0
};
},
methods: {
setValue: function(value) {
this.value = value;
}
}
}
new Vue({
el: '#app',
components: {
'child-component': ChildComponent
},
methods: {
click: function() {
this.$refs.childComponent.setValue(2.0);
}
}
})
有关更多信息,请参阅refs 上的 Vue 文档。
您所描述的是父级中的状态更改。您通过props将其传递给孩子。正如你所建议的,你会watch
那个props。当孩子采取行动时,它会通过 通知父母emit
,然后父母可能会再次更改状态。
如果你真的想将事件传递给孩子,你可以通过创建一个总线(它只是一个 Vue 实例)并将它作为 prop 传递给孩子来实现。
您可以使用$emit
和$on
。使用@RoyJ 代码:
html:
<div id="app">
<my-component></my-component>
<button @click="click">Click</button>
</div>
javascript:
var Child = {
template: '<div>{{value}}</div>',
data: function () {
return {
value: 0
};
},
methods: {
setValue: function(value) {
this.value = value;
}
},
created: function() {
this.$parent.$on('update', this.setValue);
}
}
new Vue({
el: '#app',
components: {
'my-component': Child
},
methods: {
click: function() {
this.$emit('update', 7);
}
}
})
在子组件上调用方法的一种简单的解耦方法是从子组件发出处理程序,然后从父组件调用它。
var Child = {
template: '<div>{{value}}</div>',
data: function () {
return {
value: 0
};
},
methods: {
setValue(value) {
this.value = value;
}
},
created() {
this.$emit('handler', this.setValue);
}
}
new Vue({
el: '#app',
components: {
'my-component': Child
},
methods: {
setValueHandler(fn) {
this.setter = fn
},
click() {
this.setter(70)
}
}
})
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.17/dist/vue.js"></script>
<div id="app">
<my-component @handler="setValueHandler"></my-component>
<button @click="click">Click</button>
</div>
父进程跟踪子处理程序函数并在必要时调用。
不喜欢的事件总线方式使用$on
绑定在期间孩子create
。为什么?后续create
调用(我正在使用vue-router
)不止一次绑定消息处理程序——导致每条消息有多个响应。
通过props下来从父到子,并把财产观察者在孩子的正统解决方案工作一点更好。唯一的问题是孩子只能对value转变采取行动。多次传递相同的消息需要某种簿记来强制转换,以便孩子可以接受更改。
我发现如果我将消息包装在一个数组中,它总是会触发子观察者——即使值保持不变。
家长:
{
data: function() {
msgChild: null,
},
methods: {
mMessageDoIt: function() {
this.msgChild = ['doIt'];
}
}
...
}
孩子:
{
props: ['msgChild'],
watch: {
'msgChild': function(arMsg) {
console.log(arMsg[0]);
}
}
}
HTML:
<parent>
<child v-bind="{ 'msgChild': msgChild }"></child>
</parent>