最近在做一個 Vue 的管理系統,有幾個頁面使用了同一個組件。想使用 vue-bus 進行組件間的通信,子組件發佈消息,在父組件的 created 中用 on 監聽,然後在父組件的 beforeDestory 中使用 off 銷燬(否則會重複多次觸發事件)。遇到了一個問題,在使用相同組件的頁面間切換後,子組件發佈消息時,父組件接收不到,必須刷新一次當前頁面纔可收到消息。後來發現原因在於 Vue 的生命週期。
測試了一下跳轉頁面時,兩個頁面的生命週期鉤子的執行順序,代碼如下:
// 頁面1
beforeCreate () {
console.log('1: beforeCreate');
},
created () {
console.log('1: created');
},
beforeMount () {
console.log('1: beforeMount');
},
mounted () {
console.log('1: mounted');
},
beforeUpdate () {
console.log('1: mounted');
},
updated () {
console.log('1: updated');
},
beforeDestroy () {
console.log('1: beforeDestroy');
},
destroyed () {
console.log('1: destroyed');
}
// 頁面2
beforeCreate () {
console.log('2: beforeCreate');
},
created () {
console.log('2: created');
},
beforeMount () {
console.log('2: beforeMount');
},
mounted () {
console.log('2: mounted');
},
beforeUpdate () {
console.log('2: mounted');
},
updated () {
console.log('2: updated');
},
beforeDestroy () {
console.log('2: beforeDestroy');
},
destroyed () {
console.log('2: destroyed');
}
跳轉頁面時控制檯輸出結果:
由此得出,跳轉頁面時,生命週期鉤子函數的觸發順序是:新頁面 beforeCreate → 新頁面 created → 新頁面 beforeMount → 舊頁面 beforeDestroy → 舊頁面 destroyed → 新頁面 mounted。猜想可能是新頁面在created中創建的 on 監聽事件被舊頁面在 beforeDestroy 中使用 off 銷燬了,所以把父組件的 on 寫在了 mounted 中,問題解決。