EventBus|EventBus 在vue的实现

接上篇文章,因为Vue3中已经移除实例的$on,$off方法,这次来实现一个EventBus小工具,把它封装成一个类方便调用。
单例模式 一个vue应用中,我们只需要这个类的单例模式来管理事件,所以它应该是下面的样子:
class Listener { constructor() { this.name = "Listener" this.store = {} }static getInstance() { if (!Listener.instance) { Listener.instance = new Listener() } return Listener.instance }/** * 同一个事件可多次注册,可能触发时执行多次 * @param evtName * @param cb */ $on(evtName, cb) { if (typeof cb !== 'function') { console.error(`[${this.name}] can't listen event:${evtName}, cb is not a function`) return } if (!(evtName in this.store)) { this.store[evtName] = [] } this.store[evtName].push(cb) console.log(`[${this.name}] listen on event:${evtName}, cb: ${cb.name}`) }$emit(evtName, ...data) { if (evtName in this.store) { this.store[evtName].forEach(cb => { cb(...data) }) } else { console.error(`[${this.name}] could not found event:${evtName}`) } }/** * 卸载一个事件,如果没有传入cb会被所有cb都清除 * @param evtName * @param cb */ $off(evtName, cb) { if (evtName in this.store) { if (cb) { const index = this.store[evtName].indexOf(cb) if (index > -1) { this.store[evtName].splice(index, 1) console.log(`[${this.name}] remove event:${evtName} cb: ${cb.name}`) } return } delete this.store[evtName] console.log(`[${this.name}] deleted event:${evtName}`) return null } console.warn(`[${this.name}] event:${evtName} not exist`) } }export const VueListener = { install: (Vue) => { Vue.prototype.$listener = Listener.getInstance() } }export const MyListener = Listener.getInstance()

从代码尾部导出可以看出,我们既可以把它当成vue插件使用,也可以当成一个js库使用。
npm 安装 为了方便安装使用,我已经把它发布到了npm官方网站,可以直接添加到项目依赖使用即可 listener_leo
npm i listener_leo --save // or yarn add listener_leo

使用方法:
import Vue from 'vue' import VueListener from 'listener_leo'Vue.use(VueListener)

【EventBus|EventBus 在vue的实现】这样就可以在组件中使用了:
this.$listener.$emit() this.$listener.$on() this.$listener.$off()

    推荐阅读