简单实现发布-订阅模式,从功能上来说,也叫观察者模式,他俩唯一的区别就是发布-订阅模式有一个统一的调度中心,这里不做细的区分。
var event={
//储存订阅的事件表
eventList:{},
//监听事件
listen:function(key,fn){
if(!this.eventList[key]){
//如果没有key类型事件,创建一个新的数组,用于存放key类型事件
this.eventList[key]=[]
}
//将事件函数放入同类型的事件列表里
this.eventList[key].push(fn)
},
//触发事件
trigger:function(){
var key = [].shift.call(arguments),
list=this.eventList[key]
//如果没有key类型事件或者key类型事件列表为空,直接返回,不做任何操作
if(!list||list.length===0){
return false
}
//顺序执行key类型的事件列表
for(var i=0,fn;fn=list[i++];){
fn.apply(this,arguments)
}
},
//移除事件
removeListener:function(key,fn){
var list = this.eventList[key]
//如果没有传入的key类型事件,直接返回
if(!list||list.length===0){
return false
}
//如果没有传入具体某个事件,将key类型事件列表全部移除
if(!fn){
list.length=0
return true
}
for(var i=list.length-1,newFn;newFn=list[i];i--){
if(fn===newFn){
//移除传入的事件
list.splice(i,1)
}
}
}
}
//使用
function foo(data){
console.log(`Will be remove:${data}`)
}
//监听两次相同的事件clicks,不同的处理函数
event.listen("clicks",function(data){
console.log("clicks",data)
})
event.listen("clicks",foo)
//两个函数都触发了
event.trigger("clicks"," hello!")
// clicks hello!
// Will be remove: hello!
//移除一个函数事件
event.removeListener("clicks",foo)
//只触发了一个
event.trigger("clicks"," hello!")
// clicks hello!
是不是和window.addEventListener
还有window.removeEventListener
很像?复制上边的代码到F12控制台,可以看到效果。
上一篇:element-ui的form数组表单验证(循环表单验证)
下一篇:vue3在单个组件实例上创建多个v-model 绑定