手写实现简单的Vue事件总线
Posted 小小白学计算机
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了手写实现简单的Vue事件总线相关的知识,希望对你有一定的参考价值。
一、什么是事件总线
自定义事件总线属于一种观察者模式,其中包括三个角色:
- 发布者(Publisher):发出事件(Event);
- 订阅者(Subscriber):订阅事件(Event),并且会进行响应(Handler);
- 事件总线(EventBus):无论是发布者还是订阅者都是通过事件总线作为中台的;
当然我们可以选择一些第三方的库:
- Vue2默认是带有事件总线的功能;
- Vue3中推荐一些第三方库,比如mitt;
二、手写实现事件总线
当然我们也可以实现自己的事件总线:
- 事件的监听方法on:存储对应事件名需要执行的事件函数
- 事件的发射方法emit:执行对应事件名需要执行的事件函数
- 事件的取消监听off:删除对应事件名需要执行的事件函数
运行结果:
// eventBus对象:
//
// abc: [
// 需要监听的函数, 为需要监听的事件函数绑定的this,
// 需要监听的函数, 为需要监听的事件函数绑定的this
// ]
//
class EventBus
constructor()
this.eventBus =
/*
* on函数:
* 被调用时,需要把eventCallback和thisArg放到一个对象中,然后把这个对象push到一个数组里,
* 然后把eventName作为key,把这个数组作为value存到eventBus对象中
* eventName:需要监听的事件名称
* eventCallback:需要监听的事件函数
* thisArg:为需要监听的事件函数绑定this
*/
on(eventName, eventCallback, thisArg)
let handlers = this.eventBus[eventName]
if (!handlers)
// 如果在eventBus对象中找不到key为eventName的handlers,
// 则创建一个handlers空数组,并放到eventBus对象中
handlers = []
this.eventBus[eventName] = handlers
// 如果handlers存在,则把需要监听的eventCallback函数、函数需要绑定的this
// 以对象的形式存到handlers中
handlers.push(
eventCallback,
thisArg
)
/*
* emit函数:
* 一旦被调用,则需要执行eventBus对象中key为eventName所对应的的数组中
* 的每个对象中的eventCallback函数
*/
emit(eventName, ...payload)
// 获取eventBus对象中key为eventName所对应的的数组
const handlers = this.eventBus[eventName]
if (!handlers) return
// 如果数组存在则遍历数组,调用需要执行的事件函数
handlers.forEach(handler =>
handler.eventCallback.apply(handler.thisArg, payload)
)
/*
* off函数:
* 被调用时,删除eventBus中key为eventName,
* value为一个handler对象,且该对象中的eventCallback属性与off函数第二个参数相等的这个value对象
*/
off(eventName, eventCallback)
// 获取eventBus对象中key为eventName所对应的的数组
const handlers = this.eventBus[eventName]
if (!handlers) return
// 复制handlers,然后使用newHandlers新数组来进行遍历,确保遍历的数组是始终保持不变的
// 防止出现后续删除某个handlers数组中的对象后,在进行遍历时出现问题
const newHandlers = [...handlers]
// 遍历newHandlers
for (let i = 0; i < newHandlers.length; i++)
// 获取newHandlers中的每个handler
const handler = newHandlers[i]
// 如果handler的eventCallback 等于 参数中传进来的eventCallback,
// 则获取到这个handler对象在handlers数组中的下标,然后删除这个handler对象
if (handler.eventCallback === eventCallback)
const index = handlers.indexOf(handler)
handlers.splice(index, 1)
// 以下为测试代码:
const eventBus = new EventBus()
// main.js文件
eventBus.on('abc', function (payload)
console.log('监听abc事件', this, payload)
, name: 'zep')
const handleCallback = function (payload)
console.log('监听abc事件', this, payload)
eventBus.on('abc', handleCallback, name: 'lala')
// utils.js文件
eventBus.emit('abc', 123)
eventBus.off('abc', handleCallback)
eventBus.emit('abc', 123)
以上是关于手写实现简单的Vue事件总线的主要内容,如果未能解决你的问题,请参考以下文章