Vue事件匯流排(EventBus)使用詳細介紹

jerrysun發表於2021-09-09

前言

vue元件非常常見的有父子元件通訊,兄弟元件通訊。而父子元件通訊就很簡單,父元件會透過 props 向下傳資料給子元件,當子元件有事情要告訴父元件時會透過 $emit 事件告訴父元件。今天就來說說如果兩個頁面沒有任何引入和被引入關係,該如何通訊了?

圖片描述

如果我們們的應用程式不需要類似Vuex這樣的庫來處理元件之間的資料通訊,就可以考慮Vue中的 事件匯流排 ,即 **EventBus**來通訊。

EventBus的簡介

EventBus 又稱為事件匯流排。在Vue中可以使用 EventBus 來作為溝通橋樑的概念,就像是所有元件共用相同的事件中心,可以向該中心註冊傳送事件或接收事件,所以元件都可以上下平行地通知其他元件,但也就是太方便所以若使用不慎,就會造成難以維護的“災難”,因此才需要更完善的Vuex作為狀態管理中心,將通知的概念上升到共享狀態層次。

如何使用EventBus

圖片描述

一、初始化
首先需要建立事件匯流排並將其匯出,以便其它模組可以使用或者監聽它。我們可以透過兩種方式來處理。先來看第一種,新建立一個 .js 檔案,比如 event-bus.js

// event-bus.js
import Vue from 'vue'
export const EventBus = new Vue()

實質上EventBus是一個不具備 DOM 的元件,它具有的僅僅只是它例項方法而已,因此它非常的輕便。

另外一種方式,可以直接在專案中的 main.js 初始化 EventBus :

// main.js
Vue.prototype.$EventBus = new Vue()

注意,這種方式初始化的 EventBus 是一個 全域性的事件匯流排 。稍後再來聊一聊全域性的事件匯流排。

現在我們已經建立了 EventBus ,接下來你需要做到的就是在你的元件中載入它,並且呼叫同一個方法,就如你在父子元件中互相傳遞訊息一樣。

二、傳送事件
圖片描述

假設你有兩個Vue頁面需要通訊: A 和 B ,A頁面 在按鈕上面繫結了點選事件,傳送一則訊息,想=通知 B頁面。

<!-- A.vue -->
<template>
    <button @click="sendMsg()">-</button>
</template>

<script> 
import { EventBus } from "../event-bus.js";
export default {
  methods: {
    sendMsg() {
      EventBus.$emit("aMsg", '來自A頁面的訊息');
    }
  }
}; 
</script>

接下來,我們需要在 B頁面 中接收這則訊息。

三、接收事件
圖片描述

<!-- IncrementCount.vue -->
<template>
  <p>{{msg}}</p>
</template>

<script> 
import { 
  EventBus 
} from "../event-bus.js";
export default {
  data(){
    return {
      msg: ''
    }
  },
  mounted() {
    EventBus.$on("aMsg", (msg) => {
      // A傳送來的訊息
      this.msg = msg;
    });
  }
};
</script>

同理我們也可以在 B頁面 向 A頁面 傳送訊息。這裡主要用到的兩個方法:

// 傳送訊息
EventBus.$emit(channel: string, callback(payload1,))

// 監聽接收訊息
EventBus.$on(channel: string, callback(payload1,))

前面提到過,如果使用不善,EventBus 會是一種災難,到底是什麼樣的“災難”了?大家都知道vue是單頁應用,如果你在某一個頁面重新整理了之後,與之相關的EventBus會被移除,這樣就導致業務走不下去。還要就是如果業務有反覆操作的頁面,EventBus 在監聽的時候就會觸發很多次,也是一個非常大的隱患。這時候我們就需要好好處理 EventBus 在專案中的關係。通常會用到,在vue頁面銷燬時,同時移除EventBus 事件監聽。

移除事件監聽者

圖片描述

如果想移除事件的監聽,可以像下面這樣操作:

import { 
  eventBus 
} from './event-bus.js'
EventBus.$off('aMsg', {})

你也可以使用 EventBus.$off('aMsg') 來移除應用內所有對此某個事件的監聽。或者直接呼叫 EventBus.$off() 來移除所有事件頻道,不需要新增任何引數 。

上面就是 EventBus 的使用方法,是不是很簡單。上面的示例中我們也看到了,每次使用 EventBus 時都需要在各元件中引入 event-bus.js 。事實上,我們還可以透過別的方式,讓事情變得簡單一些。那就是建立一個全域性的 EventBus 。接下來的示例向大家演示如何在Vue專案中建立一個全域性的 EventBus

全域性EventBus

它的工作原理是釋出/訂閱方法,通常稱為 Pub/Sub

建立全域性EventBus

var EventBus = new Vue();

Object.defineProperties(Vue.prototype, {
  $bus: {
    get: function () {
      return EventBus
    }
  }
})

在這個特定的匯流排中使用兩個方法 $on$emit 。一個用於建立發出的事件,它就是 $emit ;另一個用於訂閱 $on

var EventBus = new Vue();

this.$bus.$emit('nameOfEvent', { ... pass some event data ...});

this.$bus.$on('nameOfEvent',($event) => {
  // ...
})

然後我們可以在某個Vue頁面使用 this.$bus.$emit("sendMsg", '我是web秀');,另一個Vue頁面使用

this.$bus.$on('updateMessage', function(value) {
  console.log(value); // 我是web秀
})

同時也可以使用this.$bus.$off('sendMsg')來移除事件監聽。

總結

本文主要透過簡單的例項學習了Vue中有關於 EventBus 相關的知識點。主要涉及了 EventBus 如何例項化,又是如何透過 $emit 傳送頻道訊號,又是如何透過 $on 來接收頻道訊號。最後簡單介紹瞭如何建立全域性的 EventBus 。從例項中我們可以瞭解到, EventBus 可以較好的實現兄弟元件之間的資料通訊。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/151/viewspace-2823249/,如需轉載,請註明出處,否則將追究法律責任。

相關文章