在vue中 通过$on订阅事件,通过$emit触发事件以此可用来事件跨组件传值等功能,但是有个弊端就是通过这种方式订阅的事件可能会触发多次。
特别是通过$on订阅的事件中如果有http请求,将会造成触发一次会发出很多同样的http请求,造成资源浪费。
因此 对事件机制做出一下改造,保证同一个事件触发一次,订阅的事件只执行一次
代码如下:
class Event{
handlers = {};
on(eventType,handleObj){
if (!this.handlers[eventType]){
this.handlers[eventType] = {};
}
this.handlers[eventType][handleObj.name] = handleObj.fun;
return this;
}
emit(...data){
// 第一个参数为:事件类型(eventType)剩下的为参数params
let eventType = data[0], params = data.slice(1);
if (this.handlers[eventType]){
for (name in this.handlers[eventType]){
this.handlers[eventType][name].apply(this, params)
};
}else{
console.error(`没有订阅 ${eventType} 事件`)
}
return this;
}
off(...data) {// ('事件类型','事件1name','事件2name','事件3name',...)
let eventType = data[0], handles = data.slice(1);
handles.forEach(handName=>{
delete this.handlers[eventType][handName]
});
return this;
}
}
export default new Event();
event.js
在vue项目中的使用:
首先在min.js中引入event.js
然后赋给vue.prototype
具体操作如下:
import E from './utils/event'
Vue.prototype.E = E;
在组件中使用:
1 /**
2 * 订阅事件
3 */
4 this.E.on('hahaha', {
5 name: 'hahaha_test',
6 fun: (a, b, c) => {
7 debugger
8 }
9 });
10 this.E.on('hahaha', {
11 name: 'hahaha_test1',
12 fun: (a, b, c) => {
13 debugger
14 // 销毁 hahaha_test 事件
15 this.E.off('hahaha', 'hahaha_test');
16 }
17 });
18 /**
19 * 触发
20 */
21 this.E.emit('hahaha', 1, 2, 3)