接上篇文章,因为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// oryarn add listener_leo
应用办法:
import Vue from 'vue'import VueListener from 'listener_leo'Vue.use(VueListener)
这样就能够在组件中应用了:
this.$listener.$emit()this.$listener.$on()this.$listener.$off()