指点成金-最美分享吧

登录

手写实现简单的Vue事件总线

佚名 举报

篇首语:本文由小编为大家整理,主要介绍了手写实现简单的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事件总线的主要内容,如果未能解决你的问题,请参考以下文章