全局事件总线:任意组件间通信
关于这个回调函数之前写过的自定义函数使用的原理很相似,只不过那个自定义函数是有父子,祖先关系利用props传递自定义函数实现数据传递
e.g:
1.这是APP里的方法,数据在哪里,方法就写在哪里。
2.通过组件语法传值给组件
<list :todos="todos" :checktodo="checktodo" :handledelete="handledelete">
</list>
3.在list组件里面利用props收到后再传值给组件
<item v-for="todo in todos" :key="todo.id" :todo="todo" :checktodo="checktodo" :handledelete="handledelete">
</item>
4.item组件里面,调用item组件props收到的里面的方法,最终会得到数据
handlecheck(id) {
// console.log(id);
// 通知APP组件的todo将done值取反
this.checktodo(id);
}
回到本文的主题(全局事件总线):
关于上图里的X,首先需要两个条件:
1.所有的组件需要看到X总线
2.需要绑定$on,$off,$emit
关于VueComponent:
1.school组件本质上是一个名为VueComponent的构造函数,且不是程序员定义的,是Vue.extenf生成的
2.只需要写<school>或<school></school>,Vue解析时会帮我创建school组件的实例对象,
3.每次调用Vue.extend,返回的都是一个全新的VueComponent
VueCopmponent.prototype._proto_===Vue.prototype
组件实例对象(VC)可以访问到Vue原型上的属性,方法
切入正题:
1.安装全局事件总线(在main.js里面)
new Vue({
render: h => h(App),
beforeCreate() {
Vue.prototype.$bus = this//安装全局事件总线,$bus就是当前应用的Vm
}
}).$mount('#app')
2.使用事件总线:
(1)接受数据:如果A组件想要接受数据,则在A组件中给$bus绑定自定义事件,事件的回调留在A组件自身
绑定自定事件时,回调要么配置在 methods中,要么用箭头函数,否则 this 指向会出问题
mounted(){
this.$bus.$on('demo',(data)=>{
console.log('data',data);
})
}
(2)提供数据:在提供数据的组件中
<button @click="sendmsg">点我发送666</button>
methods:{
sendmsg(){
this.$bus.$emit('demo',666)
}
}
3.在beforedestroy钩子中,用$of解绑当前组件所用到的数据
mounted(){
this.$bus.$on('demo',(data)=>{
console.log('data',data);
})
},
beforeDestroy() {
this.$bus.$off("demo");
}
在main.js中,定义了全局事件总线:$bus
。
$bus
定义在Vue.prototype
,因此$bus
对所有组件可见,即所有组件可通过this.$bus
访问。
$bus
被赋值为this
,即vm实例,因此$bus
拥有vm实例上的所有属性和方法,如$emit
、$on
、$off
等。
使用全局事件总线
$bus.$on
,监听事件。组件中定义了监听事件,监听demo事件;
$bus.$emit
,触发事件。组件中定义了触发事件,点击按钮执行sendMessage回调,该回调将触发demo事件。