在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)