详解事件总线是什么,并且手动实现事件总线
-
事件总线的使用方法和其作用
- 首先,拿到实现事件总线的类zdEventBus之后,在aside板块中通过它的实例对象调用它的on方法,需要传入两个参数,第一个参数代表要监听事件的名字,第二个参数则是,如果监听的事件被触发之后,要做的操作
- 其次,就是在被监听的那个事件触发的时候,也就是在nav板块中btn的onclick事件被触发后,调用一下事件总线的实例对象的emit方法,使事件总线能够知道,这个事件现在被触发了
-
手写事件总线的具体步骤
- 其实核心思想就是当开发者给on方法传入“被监听事件名”和“事件触发要做的具体操作”之后,将它们存在一个对象中
- 开发者会在“被监听事件”中调用emit方法,当“被监听事件”触发了之后,那么就会调用emit方法,我们就可以通过调用emit事件时传入的“被监听事件名”找到被存在对象中的“事件触发要做的具体操作”,然后对其调用即可
<body> <button class="nav-btn">按钮</button> <script> // 封装一个实现了事件总线具体操作的类 class zdEventBus { constructor() { this.events = {} } // 事件的监听方法 on(eventName, eventFn) { let eventKey = this.events[eventName] // 因为考虑到一个“被监听事件名”可能会对应多个操作,所以将操作都放在一个数组中,最后遍历数组,执行操作即可 if (!eventKey) { this.events[eventName] = [] } this.events[eventName].push(eventFn) } // 时间的取消监听方法 // 开发者如果想要删除某个“被监听事件名”对应的某个“事件触发要做的具体操作”,调用该方法即可 off(eventName, eventFn) { let eventKey = this.events[eventName] if (!eventKey) return eventKey.splice(eventKey.indexOf(eventFn), 1) // 如果这个“被监听事件名”对应的数组已经为空了,那么就将这个key从对象中删掉 if (eventKey.length === 0) { Reflect.deleteProperty(this.events, eventName) } } // 事件的发射方法 emit(eventName, ...args) { let eventKey = this.events[eventName] if (!eventKey) return eventKey.forEach(fn => fn(...args)); } } // nav板块中的按钮 const btnEl = document.querySelector(".nav-btn") // 拿到事件总线这个类的实例对象 const eventBus = new zdEventBus() // aside板块 const click1 = function(name, age, height) { console.log("nav-click发生了_01", name, age, height) } eventBus.on("nav-click", click1) eventBus.off("nav-click", click1) const click2 = function() { console.log("nav-click发生了_02") } eventBus.on("nav-click", click2) eventBus.off("nav-click", click2) eventBus.on("footer-click", function() { console.log("footer-click发生了_01") }) console.log(eventBus.events) // nav板块 btnEl.onclick = function() { console.log("btnEl发生点击了") eventBus.emit("nav-click", "Judy", 18, 1.88) } </script> </body>