vue eventBus 跳坑的辦法
阿新 • • 發佈:2018-04-06
點心 mes tick 簡單 bsp 寫法 不能 準備 存在
前言(feihua): 最近閑來沒事寫了一個小的demo,在小的數據傳輸上沒有必要去使用vuex,對於非父子組件的傳值方法總結了一點心得體會供大家參考(如有太low,還請大神別噴俺)
先上官方文檔:
思路:
1.定義一個空的Vue實例,作為中央事件總線。
2.A組件定義方法去觸發自定義事件
3.B組件在鉤子裏面去監聽
OK!看似很簡單,實踐起來卻賊雞兒坑,一共遇到3個問題:
1.A組件觸發的事件在B組件中可以console顯示,但是不能更新視圖。
2.A通過路由跳轉至B,第一次是無法console出傳遞過來的數值的(第二次以後就可以)。
3.第二次傳過來的數據依次是遞增的。
我們來一個一個分析解決:
問題一:最初判斷是生命周期函數出了問題,經過分析發現是可以console出來應該是this指向的問題,最初寫法:
mounted () { Bus.$on(‘msg‘, function (data) { this.message = data // this指向錯誤,該this指向Vue實例 }) }
於是分析,該this應該指當前事件,改為:
mounted () { Bus.$on(‘msg‘, (data) => { //箭頭函數沒有自己的this, 它的this是繼承而來; 默認指向在定義它時所處的對象(宿主對象),而不是執行時的對象, 定義它的時候,可能環境是window this.message = data }) }
改為箭頭函數之後就解決了傳遞過去的數據不更新視圖的問題了!
問題二:為什麽第一次在A中觸發事件,B中卻沒有打印呢?
請看圖:
上圖分別為B A組件生命周期,我們可以明確的看到跳轉至B組件的時候,A中的事件並沒有觸發,現在明白了吧,通過分析有兩種解決方案:
1.使用this.$nextTick(在下次 DOM 更新循環結束之後執行延遲回調),也就是說,等B組件dom準備完成後在觸發這個方法,親測沒問題!
2.在beforeDestroy鉤子中去觸發事件,親測有效!
問題三:傳遞的數據為什麽會遞增呢?
是因為B中的事件一直存在,所以會導致每次都會監聽上次觸發的事件,解決辦法:在B中beforeDestroy中使用Bus.$off(‘事件‘)去解綁這個事件,親測有效!
各位大佬有更好的辦法請留言!虛心指教
vue eventBus 跳坑的辦法