vue -- 事件總線 EventBus

vue -- 事件總線 EventBus

EventBus 又稱爲事件總線。在Vue中可使用 EventBus 來做爲組件傳遞數據的橋樑的,就像是全部組件共用相同的事件中心,能夠向該中心註冊發送事件或接收事件,因此組件均可以上下平行地通知其餘組件,但也就是太方便因此若使用不慎,就會形成難以維護的災難,所以才須要更完善的Vuex做爲狀態管理中心,將通知的概念上升到共享狀態層次。vue

官方推薦的狀態管理方案是 Vuex。不過若是項目不是很大,狀態管理也沒有很複雜的話,使用 Vuex 不必。

使用 EventBus

初始化

  • 第一種方式: 能夠在 main.js中,初始化 EventBus
Vue.prototype.$EventBus = new Vue()
  • 第二種方式: 建立一個 Bus.js,再建立事件總線並將其導出,以便其它模塊可使用或者監聽它
// Bus.js
import Vue from 'vue'
export const EventBus = new Vue();
你須要作的只是引入 Vue 並導出它的一個實例(在這種狀況下,我稱它爲 EventBus )。實質上它是一個不具有 DOM 的組件,它具備的僅僅只是它實例方法而已,所以它很是的輕便。

如今咱們已經建立了 EventBus ,接下來你須要作到的就是在你的組件中加載它,而且調用同一個方法,就如你在父子組件中互相傳遞消息同樣。函數

發送和接受事件

其實和 父子組件的通訊差很少,用 EventBus.$emit('emit事件名',數據) 發送, EventBus.$on("emit事件名", callback(payload1,…)) 接受post

如今假設 A 組件與 B 組件通訊this

<!-- A.vue -->
<template>
    <p>{{msgB}}</p>
    <button @click="sendMsgA()">-</button>
</template>

<script> 
import { EventBus } from "../Bus.js";
export default {
    data(){
        return {
        msg: ''
        }
    },
    mounted() {
        EventBus.$on("bMsg", (msg) => {
            // a組件接受 b發送來的消息
            this.msg = msg;
        });
    },
    methods: {
        sendMsgA() {
            EventBus.$emit("aMsg", '來自A頁面的消息'); // a 發送數據
        }
    }
}; 
</script>


<!-- B.vue -->
<template>
  <p>{{msgA}}</p>
    <button @click="sendMsgB()">-</button>
</template>

<script> 
import { EventBus } from "../event-bus.js";
export default {
    data(){
        return {
        msg: ''
        }
    },
    mounted() {
        EventBus.$on("aMsg", (msg) => {
            // b組件接受 a發送來的消息
            this.msg = msg;
        });
    },
    methods: {
        sendMsgB() {
            EventBus.$emit("bMsg", '來自b頁面的消息'); // b發送數據
        }
    }
};
</script>

若是隻監聽(接受)一次數據可使用 EventBus.$once('事件名', callback(payload1,…)prototype

移除移除事件監聽者

EventBus.$off('事件名', 回調函數)code

  • EventBus.$off('事件名', callback),只移除這個回調的監聽器。
  • EventBus.$off('事件名'),移除該事件全部的監聽器。
  • EventBus.$off(), 移除全部的事件監聽器,注意不須要添加任何參數。
// 導入咱們剛剛建立的 EventBus
import { EventBus } from '../Bus.js'

// 事件監聽函數
const clickHandler = function(clickCount) {
  console.log(`Oh, hello)`)
}

// 開始監聽事件
EventBus.$on('i-got-clicked', clickHandler);

// 中止監聽
EventBus.$off('i-got-clicked', clickHandler);

全局EventBus

全局EventBus,雖然在某些示例中不提倡使用,但它是一種很是漂亮且簡單的方法,能夠跨組件之間共享數據。事件

它的工做原理是發佈/訂閱方法,一般稱爲 Pub/Sub 。ip

因爲是全局的,必然全部事件都訂閱它, 全部組件也發佈到它,訂閱組件得到更新。也就是說全部組件都可以將事件發佈到總線,而後總線由另外一個組件訂閱,而後訂閱它的組件將獲得更新。路由

建立全局EventBus

全局事件總線只不過是一個簡單的 vue 組件。get

var EventBus = new Vue();

Object.defineProperties(Vue.prototype, {
  $bus: {
    get: function () {
      return EventBus
    }
  }
})
// 這個初始化的第一種方法,我的感受區別不大

使用 $on和$emit

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

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

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

EventBus的優缺點

缺點

  • 你們都知道vue是單頁應用,若是你在某一個頁面刷新了以後,與之相關的EventBus會被移除,這樣就致使業務走不下去。
  • 若是業務有反覆操做的頁面,EventBus在監聽的時候就會觸發不少次,也是一個很是大的隱患。這時候咱們就須要好好處理EventBus在項目中的關係。一般會用到,在vue頁面銷燬時,同時移除EventBus事件監聽。
  • 因爲是都使用一個Vue實例,因此容易出現重複觸發的情景,兩個頁面都定義了同一個事件名,而且沒有用$off銷燬(常出如今路由切換時)。

優勢

  • 解決了多層組件之間繁瑣的事件傳播。
  • 使用原理十分簡單,代碼量少。

轉載和引用

vue篇之事件總線(EventBus)
使用 Vue.js 建立全局事件總線

Vue事件總線(EventBus)使用詳細介紹
相關文章
相關標籤/搜索