Vue2.0 探索之路——組件複用重複響應的研究

前言

前段時間,同事發現一個彈窗組件被多個頁面複用,而後點擊按鈕出現了屢次響應。明明頁面都會被銷燬掉的呀,爲啥還會出現重複調用呢。html

其實之前我也碰到過一兩次,不知道啥狀況後來沒有再復現,再加上工期緊,當時就沒有引發重視。此次同事碰到了,屢次試驗復現了。才深知當時挖的大坑啊沒有填。vue

因此此次就單獨弄了個demo專門復現並解決這個問題。也但願吸收教訓,之後碰到問題都要記錄下來,儘早早早早早解決啊,否則都是坑。git

另外,文章裏的關於父子組件的全局事件監聽是錯誤的選擇,請你們不要使用這種。(可是兄弟組件能夠用文中這種全局監聽的方式)
請用官方例子(遇到問題,請多用官方,否則直接參考其餘同窗的思路極可能挖坑。這裏是之前直接搜索到eventbus的實現方式,請引覺得戒,哈哈,我就作個反面教材吧
傳送門在此github

重複響應代碼示例

首先我寫了一個dialogx的小組件,裏面只有一個點擊按鈕。當點擊的時候,會觸發一個btnClick的事件。數組

clipboard.png

而後我又寫了兩個頁面用來測試重複響應。下面是 test1.vue,至於test2也同樣,就不從新放圖了。ide

clipboard.png

而後,我們來點點點點點點!就能發現,在test2頁面發起的事件,而test1也響應了,這屬於重複響應是不符合咱們的項目須要的。測試

clipboard.png

這...是咋回事~~??ui

clipboard.png

通過查詢相關資料,肯定了問題在於沒有過去的銷燬事件響應this

好,咱們出發去加上銷燬邏輯。spa

加入銷燬操做

因而我在dialogx.vue中加入如下代碼,在路由切換組件被銷燬的時候,對btnClick事件進行銷燬。順便打印一下 this.$root看看裏面是個啥結構。

clipboard.png

而後就有了如下的操做,竟然...竟然 test2.vue 無法響應了。WTF,這又是啥狀況。

clipboard.png

clipboard.png

冷靜下來,好好分析。首先這種狀況是由於咱們加了銷燬操做致使的,因此確定是銷燬的問題。
那麼咱們繼續追蹤。發現路由切換的各類操做的順序是這樣的。

clipboard.png

這說明 什麼問題?

新頁面的created先執行,而後開始逐漸銷燬老頁面。仔細看看,咱們能發現問題,test2.vue在建立監聽事件的時候,是在dialogx.vue銷燬以前的。人家剛建立好監聽事件,因爲執行順序問題,被子組件給清除了,因此 test2.vue在點擊發射時,是攔截不到的。

好,既然由於執行順序的問題,那咱們把監聽事件註冊放在 mounted裏。

果真,成功了。

clipboard.png

再探索一下

對於事件的觸發和監聽,由於咱們這是用 eventbus實現的。爲了看看裏面具體是爲何,因而我打印了 this.$root看看更細節的是爲何。

首先,每一次監聽 this.$root.$on('btnClick')都是一次事件註冊,而後我在打印的結果裏,找到了如下內容。

clipboard.png

btnClick 是一個數組,這就意味着每一次btnClick事件註冊,都是往裏存一個處理方法。
而後爲了驗證個人想法,我把 test2.vue中的監聽事件去了,直接看咱們的 $off效果。

clipboard.png

null,這就解釋了爲何,剛纔監聽事件寫在 created裏,爲何不生效了,由於整個事件都被設置爲 null了。

總結

爲了達到組件複用不產生重複響應的問題。咱們能夠以下作。

1.在子組件裏的destroyed方法裏,對事件進行銷燬操做($off)
2.在頁面中 mounted方法中進行事件監聽。

GitHub代碼地址:https://github.com/XuXiaoGH/v...

寫在最後

此次是一次異常排查過程的記錄,若是對你有些許幫助,不妨收藏點個贊,這將是我繼續的很大動力。

ps: GIF截圖軟件是 LICEcap ,很是好用,推薦一下。

相關文章
相關標籤/搜索