发布者不直接触及到订阅者、而是由统一的第三方来完成实际的通信的操作,叫做发布-订阅模式
class EventEmitter{
constructor(){
// 用于存储事件,与回调函数之间的关系
this.handlers={}
}
// 注册事件监听器
on(eventName,cb) {
// 如果没有该事件监听器,初始化一个监听器队列
if(!this.handlers[eventName]){
this.handlers[eventName] = []
}
// 去重
if(this.handlers[eventName].indexOf(cb) === -1) {
this.handlers[eventName].push(cb)
}
}
// 触发事件监听器
emit(eventName,...ars){
// 检查是否有函数队列
if(this.handlers[eventName]){
this.handlers[eventName].forEach(cb => {
cb(...ars)
});
}
}
//移除某个事件队列里的回调函数
off(eventName,cb){
let cbs = this.handlers[eventName]
let index = cbs.indexOf(cb)
if(index > -1) {
cbs.splice(index,1)
}
}
// 为事件注册单次监听器,(事件中的回调函数执行完后,清除)
once(eventName,cb) {
const wrapper = (...ars)=>{
cb(...ars)
this.off(eventName,wrapper)
}
this.on(eventName,wrapper)
}
}
// 匿名函数无法off
const eventemitter = new EventEmitter()
let cb1 = function(a,b){console.log(a,b)}
eventemitter.on(‘click2‘,cb1)
eventemitter.on(‘click2‘,cb1)
console.log(eventemitter.handlers[‘click2‘])
eventemitter.on(‘click2‘,function(a,b){console.log(a,b)})
eventemitter.off(‘click2‘,cb1)
eventemitter.off(‘click2‘,function(a,b){console.log(a,b)})
console.log(eventemitter.handlers[‘click2‘])
创建一个 Event Bus(本质上也是 Vue 实例)并导出:
const EventBus = new Vue()
export default EventBus
在主文件里引入EventBus,并挂载到全局:
Vue.prototype.bus = bus
订阅事件:
this.bus.$on(‘someEvent‘, func)
触发事件:
this.bus.$emit(‘someEvent‘, params)
原文:https://www.cnblogs.com/seny-33/p/12678738.html