首先为事件发布和监听创建一个载体,所谓载体其实就是实例化了一个vue
这里我把eventBus挂载到全局了,调用起来比较方便;
也可以单独写个js文件,在里面export default new Vue(),在需要全局通信的组件引入写的js文件就行,用引入的js文件对事件进行发布和监听
言归正传,在main.js中,创建一个vue实例,挂载到全局根实例
1 // main.js 2 3 // 全局事件总线,创建一个vue实例,挂载到根实例 4 const bus = new Vue() 5 Vue.prototype.bus = bus 6 7 new Vue({ 8 router, 9 render: h => h(App) 10 }).$mount('#app')
在A组件中发布事件
1 // A.vue 2 3 // 发布事件告诉其他组件,学校改变了 4 this.bus.$emit("schChange", obj); 5 6 //$emit用法,第一个参数是事件名,第二个参数和第二个以后的参数是传递的参数值
在B组件中监听事件(所有组件都可监听发布的公共事件)
注意两点:1、事件的监听在mounted中进行(原因稍后解释)2、监听一定要销毁,不然会重复监听
1 // 实例挂载后 2 mounted() { 3 console.log("老师-on"); 4 // 监听学校发生改变重载数据,如果发布事件时传了多个参数,在$on第二个参数,回调函数中就传入多个参数 5 this.bus.$on("schChange", obj => { 6 this.loadTeachers(); 7 this.loadSub(); 8 }); 9 }, 10 // 实例销毁前 11 beforeDestroy() { 12 console.log("老师-off"); 13 // 避免重复监听,页面销毁时销毁监听 14 this.bus.$off("schChange"); 15 },
如果是涉及到页面跳转的两个组件间传值,可以在发布事件时用 this.nextTick(function () { // 发布事件 }) 延迟事件的发布
或者在 beforeDestroy 中发布事件
好了,解释一下为什么事件监听要放到mounted而不是created,先补一张从一位大佬那学到的一张图
从上图中可以看出来,两个组件发生替换时的生命周期是有部分重叠的,在组件1销毁前组件2已经创建好准备挂载了,也就是说组件2的created比组件1的beforeDestroy早,也就是说组件B中的 created中所监听的来自于A中的事件还没有被触发。这个时候当你A中emit事件的时候,B其实是没有监听到的。
以上纯属个人理解,可能有理解的不对的地方还请各位多多指教
附上这位大佬的分享地址
https://www.jianshu.com/p/fde85549e3b0