vue-geventbus - 一個優雅的 Vue 全域性事件處理外掛

banxi發表於2018-08-11

Vue 中全域性事件處理的傳統做法

  1. 先建立一個名為 eventBus 的全域性 Vue 例項。
const eventBus = new Vue();
export default eventBus;
複製程式碼
  1. 在 Vue 元件中使用時,一般在 mounted 生命週期中註冊事件處理函式。在 destroyed 生命週期函式中解除註冊的事件以免造成記憶體洩漏。
import { Component, Prop, Vue } from "vue-property-decorator";
import eventBus from "@/services/eventBus";

@Component
export default class HelloWorld extends Vue {
 
  mounted(){
      eventBus.$on(AppEvents.userInfoDidChanged, this.onUserInfoChanged);
  }
  
  onUserInfoChanged(){
      
  }
  
  destroyed(){
      eventBus.$off(AppEvents.userInfoDidChanged, this.onUserInfoChanged);
  }
}
複製程式碼

這樣使用起來頗為繁瑣。註冊了某一個事件之後,必須在適用的時候取消註冊。

使用 vue-geventbus 之後

這裡要介紹的 Vue 外掛 vue-geventbus 可以幫我們優雅的解決此問題。 在使用了 vue-geventbus 之後。後面我們寫全域性事件的註冊函式就可以像下面這樣寫了。

this.$gon(AppEvents.userInfoDidChanged, () => {
    
});
複製程式碼

vue-geventbus 外掛會在此 Vue 例項銷燬時自動將此例項註冊的全域性事件處理函式全部清理以避免記憶體洩漏。

注意這裡使用的是 vue-geventbus 外掛新增的擴充套件方法 $gon$on 多了一個 g,就像 LOVE 去掉一半變 LOLI(這都啥跟啥啊?)

原理

具體來說是通過 Vue 的 Mixin 機制,為 Vue 元件新增了如下 mixin

    vueClass.mixin({
      destroyed() {
        const vue = this as any;
        clazz.removeListenersByVue(vue);
      }
    });
複製程式碼

也就是在 Vue 元件例項銷燬時將此元件註冊的所有事件處理函式清理掉。 後面的整個外掛的程式碼都是為了實現此邏輯而來的。

事實上 vue-geventbus 重新實現了基本的 Vue 事件處理邏輯。下面的兩者的事件對照表,也就是說 vue-geventbus 提供了 Vue 事件處理函式的全域性事件處理函式的版本。

Vue Api vue-geventbus Api
$on $gon
$once $gonce
$emit $gemit
$off $goff

本外掛測試完善,也可以通過測試程式碼更多了了解本外掛的一些特性細節。詳情見參考倉庫中的原始碼。

相關文章