全局事件总线,相当于图示中的 "X" :

成为x的条件
1、所有组件都能看到x。
2、x要能够调用on、off、$emit几个API,分别用于绑定、解绑、触发事件。
探究一:将x放在哪能满足所有组件都能看到x这个条件?
1、可以放在window上,window.x = {},可以,但一般来说,没人往window身上添加。
2、在每次创建VueComponent之后放入其原型对象身上,但这样不对,每次调用Vue.extend,返回的都是一个全新的VueCompinent!!,因此,它们的原型对象互不相通。

以上图示:如果将X放在Vue的原型对象上,就能解决问题,所有的vc、vm都能访问到X。
探究二:如何才能让x能够调用on、off、$emit这几个API?
组件能调用on、off、emit这几个API,是因为这些API都在**Vue的原型对象** 身上的,vm和vc可以访问到。因此,将X放在Vue的原型对象上,并在beforeCreate()钩子内,让vm实例对象赋值给X,此时,X就是**vm实例对象** ,自动具备了能调用on、off、emit的功能。实际取名时,不叫X,叫**$bus**。
全局事件总线(GlobalEventBus)
1、一种组件间通信的方式,适用于任意组件间通信。
2、安装全局事件总线:
javascript
new Vue({
......
beforeCreate() {
Vue.prototype.$bus = this //安装全局事件总线,$bus就是当前应用的vm
},
......
})
3、使用事件总线:
(1)接收数据:A组件想接收数据,则在A组件中给$bus绑定自定义事件,事件的回调留在A组件自身。
javascript
methods(){
demo(data){......}
}
......
mounted() {
this.$bus.$on('xxxx',this.demo)
}
(2)提供数据:
javascript
this.$bus.$emit('xxxx',数据)
4、最好在beforeDestroy钩子中,用$off去解绑当前组件所用到的事件。