上下文
在Vue 2.0中,文档和其他文档清楚地表明,从父母到孩子的交流是通过道具进行的。
问题
父母如何通过道具告诉孩子事件发生了?
我该看个道具节目吗?这感觉不对,替代方法也是如此($emit/$on用于从子到父,而hub模型用于远程元素)。
例子
我有一个父容器,它需要告诉它的子容器,它可以在API上进行某些操作。我需要能够触发函数。
上下文
在Vue 2.0中,文档和其他文档清楚地表明,从父母到孩子的交流是通过道具进行的。
问题
父母如何通过道具告诉孩子事件发生了?
我该看个道具节目吗?这感觉不对,替代方法也是如此($emit/$on用于从子到父,而hub模型用于远程元素)。
例子
我有一个父容器,它需要告诉它的子容器,它可以在API上进行某些操作。我需要能够触发函数。
当前回答
Vue 3组合API
为子组件创建一个ref,在模板中赋值它,并使用<ref>. ref。值直接调用子组件。
<script setup>
import {ref} from 'vue';
const childComponentRef = ref(null);
function click() {
// `childComponentRef.value` accesses the component instance
childComponentRef.value.doSomething(2.0);
}
</script>
<template>
<div>
<child-component ref="childComponentRef" />
<button @click="click">Click me</button>
</div>
</template>
有几件事需要注意
如果你的子组件使用<script setup>,你需要使用defineExpose声明公共方法(例如上面的doSomething)。 如果你使用的是Typescript,详细的注释方法在这里。
Vue 3 Options API / Vue 2
给子组件一个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);
}
}
})
有关更多信息,请参阅Vue 3文档中的组件参考或Vue 2文档中的参考。
其他回答
您可以通过切换父节点中的布尔道具来模拟向子节点发送事件。
父代码:
...
<child :event="event">
...
export default {
data() {
event: false
},
methods: {
simulateEmitEventToChild() {
this.event = !this.event;
},
handleExample() {
this.simulateEmitEventToChild();
}
}
}
子代码:
export default {
props: {
event: {
type: Boolean
}
},
watch: {
event: function(value) {
console.log("parent event");
}
}
}
不喜欢在创建期间在子进程中使用$on绑定的事件总线方法。为什么?随后的create调用(我使用vue-router)将消息处理程序绑定不止一次——导致每条消息有多个响应。
传统的解决方案是将道具从父母传递给孩子,并在孩子中放置一个属性监视器。唯一的问题是,孩子只能在价值转变上采取行动。多次传递相同的消息需要某种记账来强制转换,以便子进程能够接受更改。
我发现,如果我将消息包装在一个数组中,它总是会触发子监视程序——即使值保持不变。
家长:
{
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>
在子组件上调用方法的一种简单的解耦方法是从子组件发出处理程序,然后从父组件调用它。
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>
父处理程序在必要时跟踪子处理程序函数和调用。
如果你有时间,使用Vuex存储来观察变量(即状态)或直接触发(即分派)一个动作。
Vue 3组合API
为子组件创建一个ref,在模板中赋值它,并使用<ref>. ref。值直接调用子组件。
<script setup>
import {ref} from 'vue';
const childComponentRef = ref(null);
function click() {
// `childComponentRef.value` accesses the component instance
childComponentRef.value.doSomething(2.0);
}
</script>
<template>
<div>
<child-component ref="childComponentRef" />
<button @click="click">Click me</button>
</div>
</template>
有几件事需要注意
如果你的子组件使用<script setup>,你需要使用defineExpose声明公共方法(例如上面的doSomething)。 如果你使用的是Typescript,详细的注释方法在这里。
Vue 3 Options API / Vue 2
给子组件一个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);
}
}
})
有关更多信息,请参阅Vue 3文档中的组件参考或Vue 2文档中的参考。