假设我有一个想要向一位曾祖父母发送消息的子组件,代码将是这样的,如果我错了就纠正我:
RouterModule.forRoot(appRoutes, { useHash: true }),
是否有可能直接拦截来自孩子的消息并调用曾祖父母中的点击功能而无需在每个父母处设置传递回调?
我知道我可以使用自定义数据总线https://vuejs.org/v2/guide/components.html#Non-Parent-Child-Communication,但由于我的组件已经具有父子关系,我不应该以更简单的方式通知祖父母吗?
答案 0 :(得分:8)
如果你想保持封装,那就没有了。 greatgrandparent
不应该知道child
。它知道grandparent
,但不是有子组件或有多少。原则上,您可以将grandparent
的一个实现换成另一个没有多个层的实现。或者有更多图层可以到达child
。您可以将child
放入顶级组件。
您已经了解全球事件总线的概念。不过,公共汽车不一定是全球性的。你可以把它传递给道具链。 (您可以使用greatgrandparent
本身作为公共汽车,但这会将其暴露给它的孩子;更好的卫生来制造真正的公共汽车。)
这将顶级组件与子组件区分开来:子组件将接收bus
道具,以执行它有助于实现的顶级组件的功能。顶级组件将来自总线。
Vue.component('child', {
template: `<div v-on:click="clicked">Click me</div>`,
props: ['bus'],
methods: {
clicked: function() {
this.bus.$emit('clicked', 'hello');
},
},
});
Vue.component('parent', {
template: `<child :bus="bus"></child>`,
props: ['bus']
});
Vue.component('grandparent', {
template: `<parent :bus="bus"></parent>`,
props: ['bus']
});
Vue.component('greatgrandparent', {
template: `<grandparent :bus="bus" v-on:clicked="clicked"></grandparent>`,
data() {
return {
bus: new Vue()
};
},
created() {
this.bus.$on('clicked', this.clicked);
},
methods: {
clicked: function(msg) {
console.log('message from great grandchild: ' + msg);
},
},
});
new Vue({
el: '#app'
});
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.2.6/vue.min.js"></script>
<greatgrandparent id="app"></greatgrandparent>
&#13;