我有一个像这样的Vue应用程序:
<div id="example">
<event-emitting-component @clicked="methodOnRootInstance"></event-emitting-component>
<event-emitting-component-parent></event-emitting-component-parent>
<div v-for="click in clicks">
{{ click }}
</div>
</div>
以下是它的JS:
// Child
Vue.component('event-emitting-component', {
template: '<div class="event-emitting-component" @click="$emit(\'clicked\')">Event emitter</div>'
});
// Parent
Vue.component('event-emitting-component-parent', {
template: '<div class="event-emitting-component-parent">' +
'A custom parent!'+
'<event-emitting-component></event-emitting-component>' + // <-- Please note child component
'</div>'
});
// create a root instance
new Vue({
el: '#example',
data: {
clicks : []
},
methods : {
methodOnRootInstance : function(){
this.clicks.push('Element clicked');
}
}
})
如果你想玩它,它也在这里:
https://codepen.io/EightArmsHQ/pen/QgbwPG?editors=1010
单击顶部子组件时,将在根元素上注册单击。完美。
当子组件嵌套在父组件(示例中的第二个组件)中时,显然我无法添加@clicked="methodOnRootInstance"
,因为组件内部不存在该方法。
通过多个嵌套组件传递事件的最佳方法是什么?
我在这里做了一个剥离的例子,但实际上有些组件是两层或三层深。答案(我认为是什么)在父组件内部我会有以下内容:
Vue.component('event-emitting-component-parent', {
template: '<div class="event-emitting-component-parent">' +
'A custom parent!'+
'<event-emitting-component @clicked="passClicked"></event-emitting-component>' + // <-- Please note child component
'</div>',
'methods': {
passClicked : function(){
this.$emit('clicked')
}
}
});
然后在html模板中添加相同的内容:
<event-emitting-component-parent @clicked="methodOnRootInstance"></event-emitting-component-parent>
我知道我可以让它像这样工作,但它看起来并不优雅。我已查看了文档,并且有sync
之类的功能,虽然我不认为这是我需要的,但我很难找到正确的方法。< / p>
奖金问题:vuex可以帮助这样的事情吗?
答案 0 :(得分:1)
这是问题vuex
旨在解决的问题,但是,在考虑为应用添加额外的复杂层之前,您可以使用简单的全局事件总线,这是只需要一个空的Vue
对象来发送事件,然后可以通过应用中的任何组件监听,绕过parent-child
链:
const bus = new Vue({});
Vue.component('comp-1', {
template: `<div>Comp 1 <button @click="emitClick">Click</button></div>`,
methods: {
emitClick(){
bus.$emit('comp-1-click');
}
}
})
Vue.component('comp-2', {
template: `<div><comp-1></comp-1></div>`,
})
new Vue({
el: '#app',
created(){
bus.$on('comp-1-click',() => {
console.log('Comp 1 clicked');
});
}
})
这里是JSFiddle:https://jsfiddle.net/oatLhzLp/