前言(feihua): 最近閒來沒事寫了一個小的demo,在小的數據傳輸上沒有必要去使用vuex,對於非父子組件的傳值方法總結了一點心得體會供你們參考(若有太low,還請大神別噴俺)javascript
先上官方文檔:vue
思路:java
1.定義一個空的Vue實例,做爲中央事件總線。vuex
2.A組件定義方法去觸發自定義事件dom
3.B組件在鉤子裏面去監聽函數
OK!看似很簡單,實踐起來卻賊雞兒坑,一共遇到3個問題:this
1.A組件觸發的事件在B組件中能夠console顯示,可是不能更新視圖。spa
2.A經過路由跳轉至B,第一次是沒法console出傳遞過來的數值的(第二次之後就能夠)。3d
3.第二次傳過來的數據依次是遞增的。code
咱們來一個一個分析解決:
問題一:最初判斷是生命週期函數出了問題,通過分析發現是能夠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('事件')去解綁這個事件,親測有效!
各位大佬有更好的辦法請留言!虛心指教