在vue專案中自定義事件匯流排eventHub
由於在工作中vue的專案中使用了大量是全域性事件匯流排廣播,使得某些方法在某種情況下被重複多次呼叫,檢視了一下原因,是因為在每個單檔案元件中定義的事件接收器和事件廣播器在頁面銷燬的時候沒有登出導致的。於是在保證改動量不大的前提下,決定自定義一個全域性事件匯流排檔案。
之前的使用是在 main.js 檔案中 vue.prototype.$eventHub = vue.prototype.$eventHub || new Vue()
因此,重新定義一個檔案 EventHub.js
/**
* Created by baidm in 2021/1/3 on 12:54
*/
class EventHub {
constructor(vm) {
this.vm = vm;
this.curVm = null;
this.events = {};
this.eventMapUid = {};
}
/**
* 註冊呼叫者例項
* @param vm
*/
$register(vm) {
this.curVm = vm;
}
/**
* 收集所有的事件型別
* @param uid
* @param type
*/
setEventMapUid(uid, type) {
if (!this.eventMapUid[uid]) {
this.eventMapUid[uid] = [];
}
this.eventMapUid[uid].push(type);
}
/**
* 收集每種型別的回撥
* @param type
* @param fn
*/
$on(type, fn) {
if (!this.events[type]) {
this.events[type] = [];
}
this.events[type].push(fn);
if (this.curVm instanceof this.vm) {
this.setEventMapUid(this.curVm._uid, type);
}
}
/**
* 觸發每種型別的所有回撥
* @param type
* @param args
*/
$emit(type, ...args) {
if (this.events[type]) {
this.events[type].forEach(fn => fn(...args));
}
}
/**
* 取消訂閱事件
* @param type
* @param fn
*/
$off(type, fn) {
if (fn && this.events[type]) {
const index = this.events[type].findIndex(f => f === fn);
if (index !== -1) {
this.events[type].splice(index, 1);
}
return;
}
delete this.events[type];
}
/**
* 取消uid訂閱的所有事件
* @param uid
*/
$offAll(uid) {
const curAllTypes = this.eventMapUid[uid] || [];
curAllTypes.forEach(type => this.$off(type));
delete this.eventMapUid[uid];
}
}
export default {
install(vm, options = {}) {
Reflect.defineProperty(vm.prototype, "$eventHub", {
value: new EventHub(vm)
})
}
}
然後在 main.js 檔案中定義 mixin
import Vue from 'vue'
...
import EventHub from "./EventHub"
EventHub.install(Vue);
const mixin = {
data() {
return {}
},
created() {
this.$eventHub.$register(this);
},
methods: {},
directives: {},
beforeDestroy() {
this.$eventHub.$offAll(this._uid);
}
};
Vue.mixin(mixin);
...
這樣在不改變原有程式碼中的寫法 this.$eventhub.$on() 和 this.$eventHub.$emit() 的前提下,即可在每個SFC解除安裝的時候自動下載在該元件中定義的事件廣播。
相關文章
- Vue事件匯流排(EventBus)Vue事件
- Vue 事件中央匯流排Vue事件
- 事件匯流排事件
- Flutter中的事件匯流排(EventBus)Flutter事件
- 事件匯流排demo事件
- javascript事件匯流排JavaScript事件
- 將Abp預設事件匯流排改造為分散式事件匯流排事件分散式
- Vue事件匯流排(EventBus)使用詳細介紹Vue事件
- 【vue外掛篇】vue-options-events 事件匯流排觸發Vue事件
- 實現一個事件匯流排(vue.prototype.$bus)?事件Vue
- 在 .NET 中深入瞭解事件匯流排的使用與實現事件
- SOFA 原始碼分析— 事件匯流排原始碼事件
- Otto事件匯流排框架的使用事件框架
- 如何在 JavaScript 中實現 Event Bus(事件匯流排)JavaScript事件
- 如何在 pyqt 中實現全域性事件匯流排QT事件
- 使用jQuery在javascript中自定義事件jQueryJavaScript事件
- 事件匯流排EventBus和觀察者模式事件模式
- 自己動手寫事件匯流排(EventBus)事件
- 事件匯流排有個 pipe 管道方法事件
- Otto - 安卓平臺上事件匯流排安卓事件
- 自定義Vue-cli專案模板Vue
- 匯流排
- 比 EventBus 更高效的事件匯流排(BusUtils)事件
- Flutter基礎-036-事件匯流排EventBusFlutter事件
- 事件匯流排的設計與實現事件
- Javascript中自定義事件JavaScript事件
- EventBridge 事件匯流排及 EDA 架構解析事件架構
- Android事件匯流排還能怎麼玩?Android事件
- 前端匯流排前端
- vue router路由自定義後退事件Vue路由事件
- 在vue中展示自定義列名的甘特圖Vue
- 在vue中,使用echarts的自定義主題VueEcharts
- 在Vue3中實現自定義指令Vue
- Vue中自定義指令Vue
- 風險洞察之事件匯流排的探索與演進事件
- 高吞吐量的Java事件匯流排:MBassadorJava事件
- AndroidEventBus (事件匯流排) 的設計與實現AndroidIDEdev事件
- 元件間通訊--利用mitt實現事件匯流排元件MIT事件