全局事件总线
一种组件间通信方式,适用于任意组件间通信。
规范写法
安装全局事件总线:
new Vue({
// .......
beforeCreate() {
Vue.prototype.$bus = this // 安装全局事件总线,$bus就是当前应用的vm
},
// .....
})
使用事件总线:
接收数据:
mounted() {
// 为$bus绑定studentNameEvent事件
this.$bus.$on('studentNameEvent', (studentName) => {
this.studentName = studentName
});
}
发送数据:
methods: {
sendStudentName() {
this.$bus.$emit('studentNameEvent', this.name)
}
}
最好在beforeDestroy
钩子中,使用$off
解绑当前组件所用到的事件。
其他写法
如果要满足任意组件间通信,需要所有组件都能拿到该对象。所以该对象可以有以下几种方式:
- 绑定在window对象上:
window.$bus = xxxxx
- 绑定在VueComponent原型上。因为VueComponent原型是在源码中每次都新生成一份,所以需要修改源码
- 绑定在Vue原型上。因为
VueComponent.prototype.__proto__ === Vue.prototype
,所以组件调用时,如果自身、自身原型都找不到这个对象,就会去Vue原型上查找。Vue.prototype.$bus = xxxx
极不推荐方式2修改源码。推荐使用方式3绑定在Vue原型上
该总线对象需要有$on
、$emit
、$once
等相关方法,这些方法在Vue原型上,所以需要总线对象是Vue实例或者VueComponent组件实例。
如果要将总线对象定义为组件实例对象,写法为:
const BusVCClass = Vue.extend({}); // 通过Vue.extend创建一个组件的类对象
const busVC = new BusVCClass(); // 实例化出一个组件对象
Vue.prototype.$bus = busVC // 将Vue原型上的$bus设置成组件实例对象
如果要将对象设置成Vue实例对象,则需要利用Vue的beforeCreate
钩子函数:
new Vue({
// .....
beforeCreate() {
Vue.prototype.$bus = this
}
// .....
})
以上两种方式都可以正常使用,推荐使用方式2规范写法。
其他
自定义事件被触发时,在Vue的浏览器插件中切换到事件页面,可以看到触发的事件。