js 事件发布订阅销毁
在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)