首先為事件發布和監聽創建一個載體,所謂載體其實就是實例化了一個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