我有三个嵌套组件
<parent @event="handle">
<inbetween @event="$emit('event')">
<child> // emits event
</child>
</inbetween>
</parent>
所以,当一个孩子发出这个事件时,我必须将那个恼人的部分@event="$emit('event')"
添加到其间的组件中,否则父母不会收到任何事件。
我希望它不应该那样工作。我想知道它有什么问题吗?
答案 0 :(得分:2)
这实际上是故意的。原因是,当查看一个组件的代码并且您看到它正在侦听事件时,您可以查看该模板以查看该事件的来源。如果事件可以任意深入到某个组件,那么就很难弄清楚该事件的触发方式和位置。
然而,Vue 曾经通过方法$broadcast
和$dispatch
有办法做你想做的事情,并且最终因为被谈论的原因而被删除在这里。 Here's a page from the docs which explains why, along with possible solutions, such as using a global event bus, or a centralized state management solution such as Vuex.
答案 1 :(得分:2)
是的,这应该是怎么回事。事件只从孩子到父母,而不是从孩子到父母。因此,您必须从child和inbetween组件中发出事件。
如果您想避免使用此方法,可以使用事件总线:
alligator.io/vuejs/global-event-bus
答案 2 :(得分:1)
Vue自定义事件不会冒泡。
在复杂情况下处理祖先/兄弟通信的推荐方法是使用Vuex。如果您有简单的需求,可以创建Vue实例以用作事件中心。
您将创建一个全局变量:
var eventHub = new Vue(); // use a Vue instance as event hub
发出您将在任何组件中使用的事件:
eventHub.$emit('myevent', 'some value');
并且,再次在任何组件中听取该事件,请执行:
eventHub.$on('myevent', (e) => {
console.log('myevent received', e)
});
<强>演示:强>
var eventHub = new Vue(); // use a Vue instance as event hub
Vue.component('parent', {
template: "#parent-tpl",
created() {
eventHub.$on('event', (e) => {
console.log('event received at parent! value:', e);
});
}
});
Vue.component('inbetween', {
template: "#inbetween-tpl"
});
Vue.component('child', {
template: "#child-tpl",
methods: {
emitEvent() {
eventHub.$emit('event', 123);
}
}
});
new Vue({
el: '#app',
data: {
message: 'Hello Vue.js!'
}
})
<script src="https://unpkg.com/vue/dist/vue.min.js"></script>
<template id="parent-tpl">
<div>
<inbetween></inbetween>
</div>
</template>
<template id="inbetween-tpl">
<div>
<child></child>
</div>
</template>
<template id="child-tpl">
<div>
<h1>I'm the child</h1>
<button @click="emitEvent">Trigger EVENT</button>
</div>
</template>
<div id="app">
<p>{{ message }}</p>
<parent></parent>
</div>
注意:如果在您的环境中创建专用实例作为事件中心是一件很复杂的事情,您可以将eventHub
替换为this.$root
(在您的组件中)并使用您自己的Vue实例作为集线器。