1.简介
全局事件总线时一种组件间通信的方式,适用于任意组件间通信
2.原理

分析: 如果A组件想要传递数据给B组件,那么就通过全局事件总线在B组件中绑定一个自定义事件,并界定一个参数来接收传递的数据,在A组件中,就需要通过全局事件总线对自定义事件进行触发,并传递参数
简单理解:全局事件总线其实就是一个中间介质,组件间的相互通信借助于这个中间介质,通过这个中间转换介质,从而完成数据的传递与接收,实现组件间的相互通信
一、满足所有组件都能访问得到全局事件总线
既然要能让所有组件都能访问得到全局事件总线,那么创建的思路就是,全局事件总线一定要让vc或者vm访问得到。
结合组件的内置关系:
VueComponent.prototype.proto===Vue.prototype
这个关系的作用就在于可以让组件实例对象(vc)可以访问到Vue原型上的属性和方法
二、可以调用on,off和$emit
因为on,off和$emit这三个方法在vue原型对象上,所以,我们的全局事件总线就要放在Vue的原型对象(vue.prototype)上,以确保每个组件都能访问得到
以下案例为A组件向B组件传递数据,B组件接收A组件传递过来的数据
(1)实现全局事件总线
首先,想要实现全局事件总线,就要安装全局事件总线,在main.js中完成全局事件的安装配置
main.js
//创建vm
new Vue({
el:'#app',
render: h => h(App),
// beforeCreate中模板未解析,且this是vm
beforeCreate(){
Vue.prototype.$bus = this //安装全局事件总线
}
})
(2)绑定全局事件总线
接下来,我们就要对想要接受到数据的组件进行自定义事件的绑定,简单来说就是,谁要接收数据,自定义事件即绑定在谁身上
testB.vue:
mounted(){
// 绑定自定义事件
this.$bus.$on('自定义事件名', (接收参数)=>{
console.log('我是TestB组件,收到了数据', 接收参数);
})
}
(3)触发全局事件
最后一步,全局事件总线的触发,事件的触发是在发送数据的组件中完成的,简单来说,谁是数据的发送者,谁就来触发这个事件
testA.vue
methods:{
// 触发事件,事件名不能重复
触发事件方法名(){
this.$bus.$emit('自定义事件名', 传递参数);
}
},
完整代码
main.js

testB.vue

testA.vue

我的总结:
A组件向B组件传递数据,则A组件就是使用this.bus.emit来触发自定义事件,把数据写在回调函数中,B组件通过this.bus.on来绑定自定义事件,后面的data来接收A组件传递的数据
数据传递前:

点击按钮触发全局事件总线后:

此时,数据已经传递到了testB.vue中
最后:
得到数据之后,解绑事件,提高性能
// 销毁对应自定义事件
beforeDestroy(){
this.$bus.$off('自定义事件名')
}
参考文章: