2022-01-24【技術(shù)】Vue事件總線(EventBus)使用詳細(xì)介紹

1俐巴、需求背景

vue組件非常常見(jiàn)的有父子組件通信综芥,兄弟組件通信泰演。而父子組件通信就很簡(jiǎn)單飒房,父組件會(huì)通過(guò) props 向下傳數(shù)據(jù)給子組件搁凸,當(dāng)子組件有事情要告訴父組件時(shí)會(huì)通過(guò) $emit 事件告訴父組件。今天就來(lái)說(shuō)說(shuō)如果兩個(gè)頁(yè)面沒(méi)有任何引入和被引入關(guān)系狠毯,該如何通信呢护糖?
如果咱們的應(yīng)用程序不需要類似Vuex這樣的庫(kù)來(lái)處理組件之間的數(shù)據(jù)通信,就可以考慮Vue中的 事件總線 嚼松,即 EventBus來(lái)通信嫡良。

2、EventBus的簡(jiǎn)介

EventBus 又稱為事件總線献酗。在Vue中可以使用 EventBus 來(lái)作為溝通橋梁的概念寝受,就像是所有組件共用相同的事件中心,可以向該中心注冊(cè)發(fā)送事件或接收事件罕偎,所以組件都可以上下平行地通知其他組件很澄,但也就是太方便所以若使用不慎,就會(huì)造成難以維護(hù)的“災(zāi)難”颜及,因此才需要更完善的Vuex作為狀態(tài)管理中心甩苛,將通知的概念上升到共享狀態(tài)層次。

3俏站、如何使用EventBus

一浪藻、初始化
首先需要?jiǎng)?chuàng)建事件總線并將其導(dǎo)出,以便其它模塊可以使用或者監(jiān)聽(tīng)它乾翔。我們可以通過(guò)兩種方式來(lái)處理爱葵。先來(lái)看第一種,新創(chuàng)建一個(gè) .js 文件反浓,比如 event-bus.js

// event-bus.js
import Vue from 'vue'
export const EventBus = new Vue()
實(shí)質(zhì)上EventBus是一個(gè)不具備 DOM 的組件萌丈,它具有的僅僅只是它實(shí)例方法而已,因此它非常的輕便雷则。

另外一種方式辆雾,可以直接在項(xiàng)目中的 main.js 初始化 EventBus :

// main.js
Vue.prototype.$EventBus = new Vue()
注意,這種方式初始化的EventBus是一個(gè)全局的事件總線月劈。稍后再來(lái)聊一聊全局的事件總線度迂。

現(xiàn)在我們已經(jīng)創(chuàng)建了 EventBus ,接下來(lái)你需要做到的就是在你的組件中加載它猜揪,并且調(diào)用同一個(gè)方法惭墓,就如你在父子組件中互相傳遞消息一樣。

二而姐、發(fā)送事件
假設(shè)你有兩個(gè)Vue頁(yè)面需要通信: A 和 B 腊凶,A頁(yè)面 在按鈕上面綁定了點(diǎn)擊事件,發(fā)送一則消息,想要通知 B頁(yè)面钧萍。

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

<script> 
import { EventBus } from "../event-bus.js";//引入EventBus 
export default {
  methods: {
    sendMsg() {
      EventBus.$emit("aMsg", '來(lái)自A頁(yè)面的消息');
    }
  }
}; 
</script>

接下來(lái)褐缠,我們需要在 B頁(yè)面 中接收這則消息。

三风瘦、接收事件

<!-- 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發(fā)送來(lái)的消息
      this.msg = msg;
    });
  }
};
</script>

同理我們也可以在 B頁(yè)面 向 A頁(yè)面 發(fā)送消息队魏。這里主要用到的兩個(gè)方法:

// 發(fā)送消息
EventBus.$emit(channel: string, callback(payload1,…))

// 監(jiān)聽(tīng)接收消息
EventBus.$on(channel: string, callback(payload1,…))

前面提到過(guò),如果使用不善万搔,EventBus會(huì)是一種災(zāi)難器躏,到底是什么樣的“災(zāi)難”呢?
大家都知道vue是單頁(yè)應(yīng)用蟹略,如果你在某一個(gè)頁(yè)面刷新了之后,與之相關(guān)的EventBus會(huì)被移除遏佣,這樣就導(dǎo)致業(yè)務(wù)走不下去挖炬。還要就是如果業(yè)務(wù)有反復(fù)操作的頁(yè)面,EventBus在監(jiān)聽(tīng)的時(shí)候就會(huì)觸發(fā)很多次状婶,也是一個(gè)非常大的隱患意敛。這時(shí)候我們就需要好好處理EventBus在項(xiàng)目中的關(guān)系。通常會(huì)用到膛虫,在vue頁(yè)面銷毀時(shí)草姻,同時(shí)移除EventBus事件監(jiān)聽(tīng)。

四稍刀、移除事件監(jiān)聽(tīng)
如果想移除事件的監(jiān)聽(tīng)撩独,可以像下面這樣操作:

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

你也可以使用 EventBus.off('aMsg') 來(lái)移除應(yīng)用內(nèi)所有對(duì)此某個(gè)事件的監(jiān)聽(tīng)≌嗽拢或者直接調(diào)用 EventBus.off() 來(lái)移除所有事件頻道综膀,不需要添加任何參數(shù) 。

上面就是 EventBus 的使用方法局齿,是不是很簡(jiǎn)單剧劝。上面的示例中我們也看到了,每次使用 EventBus 時(shí)都需要在各組件中引入 event-bus.js 抓歼。

但是事實(shí)上讥此,我們還可以通過(guò)別的方式,讓事情變得簡(jiǎn)單一些谣妻。那就是創(chuàng)建一個(gè)全局的 EventBus 萄喳。接下來(lái)的示例向大家演示如何在Vue項(xiàng)目中創(chuàng)建一個(gè)全局的 EventBus 。

全局EventBus

它的工作原理是發(fā)布/訂閱方法蹋半,通常稱為 Pub/Sub 取胎。

1、創(chuàng)建全局EventBus
var EventBus = new Vue();
Object.defineProperties(Vue.prototype, {
  $bus: {
    get: function () {
      return EventBus
    }
  }
})

在這個(gè)特定的總線中使用兩個(gè)方法on和emit。一個(gè)用于創(chuàng)建發(fā)出的事件闻蛀,它就是emit匪傍;另一個(gè)用于訂閱on:

var EventBus = new Vue();
this.$bus.$emit('nameOfEvent', { ... pass some event data ...});
this.$bus.$on('nameOfEvent',($event) => {
  // ...
})

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

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

同時(shí)也可以使用this.bus.off('sendMsg')來(lái)移除事件監(jiān)聽(tīng)觉痛。

總結(jié)

本文主要通過(guò)簡(jiǎn)單的實(shí)例學(xué)習(xí)了Vue中有關(guān)于 EventBus 相關(guān)的知識(shí)點(diǎn)役衡。主要涉及了 EventBus 如何實(shí)例化,又是如何通過(guò) emit 發(fā)送頻道信號(hào)薪棒,又是如何通過(guò)on 來(lái)接收頻道信號(hào)手蝎。最后簡(jiǎn)單介紹了如何創(chuàng)建全局的 EventBus 。從實(shí)例中我們可以了解到俐芯, EventBus 可以較好的實(shí)現(xiàn)兄弟組件之間的數(shù)據(jù)通訊棵介。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市吧史,隨后出現(xiàn)的幾起案子邮辽,更是在濱河造成了極大的恐慌,老刑警劉巖贸营,帶你破解...
    沈念sama閱讀 216,744評(píng)論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件吨述,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡钞脂,警方通過(guò)查閱死者的電腦和手機(jī)揣云,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,505評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)冰啃,“玉大人邓夕,你說(shuō)我怎么就攤上這事⊙忠悖” “怎么了翎迁?”我有些...
    開(kāi)封第一講書人閱讀 163,105評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)净薛。 經(jīng)常有香客問(wèn)我汪榔,道長(zhǎng),這世上最難降的妖魔是什么肃拜? 我笑而不...
    開(kāi)封第一講書人閱讀 58,242評(píng)論 1 292
  • 正文 為了忘掉前任痴腌,我火速辦了婚禮,結(jié)果婚禮上燃领,老公的妹妹穿的比我還像新娘士聪。我一直安慰自己,他們只是感情好猛蔽,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,269評(píng)論 6 389
  • 文/花漫 我一把揭開(kāi)白布剥悟。 她就那樣靜靜地躺著灵寺,像睡著了一般。 火紅的嫁衣襯著肌膚如雪区岗。 梳的紋絲不亂的頭發(fā)上略板,一...
    開(kāi)封第一講書人閱讀 51,215評(píng)論 1 299
  • 那天,我揣著相機(jī)與錄音慈缔,去河邊找鬼叮称。 笑死,一個(gè)胖子當(dāng)著我的面吹牛藐鹤,可吹牛的內(nèi)容都是我干的瓤檐。 我是一名探鬼主播,決...
    沈念sama閱讀 40,096評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼娱节,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼挠蛉!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起肄满,我...
    開(kāi)封第一講書人閱讀 38,939評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤谴古,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后悄窃,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,354評(píng)論 1 311
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡蹂窖,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,573評(píng)論 2 333
  • 正文 我和宋清朗相戀三年轧抗,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片瞬测。...
    茶點(diǎn)故事閱讀 39,745評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡横媚,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出月趟,到底是詐尸還是另有隱情灯蝴,我是刑警寧澤,帶...
    沈念sama閱讀 35,448評(píng)論 5 344
  • 正文 年R本政府宣布孝宗,位于F島的核電站穷躁,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏因妇。R本人自食惡果不足惜问潭,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,048評(píng)論 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望婚被。 院中可真熱鬧狡忙,春花似錦、人聲如沸址芯。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 31,683評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至北专,卻和暖如春禀挫,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背逗余。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 32,838評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工特咆, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人录粱。 一個(gè)月前我還...
    沈念sama閱讀 47,776評(píng)論 2 369
  • 正文 我出身青樓腻格,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親啥繁。 傳聞我的和親對(duì)象是個(gè)殘疾皇子菜职,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,652評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容

  • vue組件非常常見(jiàn)的有父子組件通信,兄弟組件通信旗闽。而父子組件通信就很簡(jiǎn)單酬核,父組件會(huì)通過(guò) props 向下傳數(shù)據(jù)給子...
    Kinderzhu閱讀 2,179評(píng)論 0 2
  • Vue事件總線 (EventBus)可以稱之為事件總線,當(dāng)兩個(gè)組件屬于不同的兩個(gè)組件分支适室,或者兩個(gè)組件沒(méi)有任何聯(lián)系...
    不是山谷_50e2閱讀 6,511評(píng)論 0 6
  • 闡述一下 VUE中 eventbus 的原理 解答:EventBus是消息傳遞的一種方式嫡意,基于一個(gè)消息中心,訂閱和...
    _皓月__閱讀 1,451評(píng)論 0 0
  • vue組件非常常見(jiàn)的有父子組件通信捣辆,兄弟組件通信蔬螟。而父子組件通信就很簡(jiǎn)單,父組件會(huì)通過(guò) props 向下傳數(shù)據(jù)給子...
    Jason杰森閱讀 1,061評(píng)論 0 7
  • vue組件中的數(shù)據(jù)傳遞最最常見(jiàn)的就是父子組件之間的傳遞。父?jìng)髯油ㄟ^(guò)props向下傳遞數(shù)據(jù)給子組件忍些;子傳父通過(guò)$em...
    zhao_ran閱讀 10,973評(píng)論 0 9