Vue 之全局事件總線和消息訂閱與發布


之前我們實現了子組件向父組件傳遞數據,很明顯,這是不夠的,看完這篇博客,無論哪兩個組件之間傳遞和接收數據都沒有問題!

全局事件總線(適用於任意組件間通信) 原理:(看圖理解)

1.png

主要就是通過往 x 身上放事件,然后事件的回調要放在想要獲取數據的組件身上,誰要傳數據就調用 x 身上對應的事件並往里面存數據就可以了,相當於一個中間商(哎,不得不說,它一出生就被利用了)

當然不是誰都能但此大任的,x 需要具備兩個條件:

  1. 所有組件都可以看到

  2. x 身上有 on、on 、on、off 、$emit 方法

統一給 x 命名為 $bus

我們將其定義在 main.js 文件中,創建在 vm 的實例對象身上,因為 vm 實例對象只有一個

創建全局事件總線有兩種方法:

1、

const Demo = Vue.extend({})

const d = new Demo()

Vue.prototype.$bus = d

(定義在創建 Vue 的外面)

2、

 new Vue({

    ......
    
      beforeCreate(){
      Vue.prototype.$bus = this //安裝全局事件總線, $bus 就是當前應用的 vm

   },

})
復制代碼
    

    new Vue({

    render: h => h(App),
  
    beforeCreate(){
  
    Vue.prototype.$bus = this  //安裝全局事件總線
    }
  
    }).$mount('#app')
復制代碼

使用事件總線:

  1. 接收數據:A 組件想接收數據,則在 A 組件中給 $bus 綁定自定義事件,事件的回調留在 A 組件自身

mounted() { //或者后面指向的是一個方法,方法在 methods 里面定義 //在全局事件總線 bus中綁定一個hello事件,后面的回調是箭頭函數,用於接收數據this.bus 中綁定一個 hello 事件,后面的回調是箭頭函數,用於接收數據 this.bushello調this.bus.$on("hello", (value) => { console.log("我獲取到了數據", value); }); },

  1. 提供數據:

methods: { sentMyName(){ //在該方法中觸發 hello 這個事件,把數據傳過去 this.bus.bus.bus.emit('hello',this.myName) } }, 用這個方法的好處就是!我們就不需要再在標簽里綁定自定義事件了,直接把事件在 $bus 里創建,再在要傳數據的地方調用它就可以了!

當然還有個注意點,如果某個事件或綁定事件的組件你不用了,那要養成隨時解綁的好習慣!不要占着空間不用,會導致空間浪費從而出現卡頓

最好在 beforeDestroy 鈎子中,用 $off 去解綁當前組件所用到的事件

在綁定事件的組件中解綁(即需要數據的組件)

beforeDestroy() { //解綁 bus中名為hello的事件this.bus 中 名為 hello 的事件 this.bushellothis.bus.off("hello"); }, 切記!this.bus.off()里面一定要寫要解綁的事件,不然off() 里面一定要寫要解綁的事件,不然 off()然bus 中所有的事件都會被解綁!后果很嚴重!!!!

消息訂閱與發布(適用於任意組件間通信) 原理:

2.png

簡單理解:

需要數據的組件:訂閱消息 提供數據的組件:發布消息

這個相比第一種方法就要麻煩那么一丟丟了,它需要安裝 pubsub,我們打開 VScode 的控制台,輸入 npm i pubsub-js,進行安裝

在傳數據和接收數據的組件中都要通過 import pubsub from 'pubsub-js' 引入這個文件

然后就可以開始使用了

接收數據:A 組件想接收數據,則在 A 組件中訂閱消息,訂閱的回調留在 A 組件自身

this.pubId = pubsub.subscribe('hello',(msgName,data)=>{
  console.log('我接收到數據了',data);
})
復制代碼

這里有一個注意點,那就是回調函數的第一個參數 msgName,代表的是 hello,即訂閱的消息名,這個必須要寫,因為默認第一個參數就是消息名,第二個參數才是數據,前端培訓所以不管如何,第一個要占個位,你可以給它取個名字,或者用下划線 _ 占位

提供數據:

methods: { sentMyName(){ pubsub.publish('hello',this.myName) } }, 當然如果訂閱的消息不用了,也要將其刪除,不能占用空間,但是刪除訂閱消息不是用 $off ,而是 publish.unsubscribe(this.pubId),其中 this.pubId 是每個消息創建的時候都會有一個 id,就像定時器一樣,我們刪除就刪除它對應的 id 號就可以了

beforeDestroy() { pubsub.unsubscribe(this.pubId) }, 對比兩者我們用的更多的是前者,因為它是 Vm 里面創建的,不需要再導入包

最后再分享一個方法:

bbfff49165ad4d23baf60b9ef637d64f.png

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM