实现一个Event类
使用ES6实现一个事件类Event,包含了下面功能:绑定事件、解绑事件和派发事件。
on(eventName,func())
:监听eventName
事件,事件触发的时候调用func函数;emit(eventName, arg1,arg2,arg3....)
:触发eventName
事件,并且把参数arg1、arg2、arg3...
传给事件处理函数;off(eventName, func)
: 停止监听某个事件。
实现Event类的核心其实就是发布订阅模式,即组件间通信使用事件监听和派发的方式,而不是直接相互调用组件方法。
核心思想:
- 为了实现绑定事件需要_cache对象记录绑定了那些事件。
- 事件发生时,需要从_cache中读取出来事件回调,以此执行他们。
- 一般页面中事件派发(读)要比事件绑定(写)多,因此设计数据结构时,需要在事件发生时,更加快速的找到对应事件的回调函数,然后执行。
class Event {
constructor () {
// 储存事件的数据结构
// 为了快速查找,使用对象
this._cache = {}
}
// 事件绑定
on(type, callback) {
// 为了按类查找方便和节省空间
// 将同一类型事件被放到同一个数组里
// 这里的数据是队列,遵循先进先出原则
let fns = (this._cache[type] = this._cache[type] || []);
if(fns.indexOf(callback) === -1) {
fns.push(callback)
}
return this;
}
// 事件触发
// emit
trigger(type,data) {
let fns = this._cache[type];
if(Array.isArray(fns)) {
fns.forEach(fn=>{
fn(data);
})
}
return this;
}
// 解绑
off(type,callback) {
let fns = this._cache[type];
if(Array.isArray(fns)) {
if(callback) {
let index = fns.indexOf(callback);
if(index !== -1) {
fns.splice(index,1);
}else {
// 清空
fns.length = 0;
}
}
}
return this;
}
}
vue里面的中央事件总线就与此一样。
写在后面:该文章学习于实现一个Event类