美文网首页
事件总线

事件总线

作者: 未路过 | 来源:发表于2022-10-10 09:21 被阅读0次

自定义事件总线属于一种观察者模式,其中包括三个角色:

  1. 发布者(Publisher):发出事件(Event);

  2. 订阅者(Subscriber):订阅事件(Event),并且会进行响应(Handler);

  3. 事件总线(EventBus):无论是发布者还是订阅者都是通过事件总线作为中台的;

当然我们可以选择一些第三方的库:

  1. Vue2默认是带有事件总线的功能;

  2. Vue3中推荐一些第三方库,比如mitt;

当然我们也可以实现自己的事件总线:

  1. 事件的监听方法on;

  2. 事件的发射方法emit;

  3. 事件的取消监听off;

手写事件总线

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <button class="nav-btn">nav button</button>
    <script>
      // 类EventBus -> 事件总线对象
      class EventBus {
        constructor() {
          this.eventMap = {}; //{onclick:[fn1,fn2,fn3]}
        }
        on(eventName, eventFn) {
          let eventFns = this.eventMap[eventName];
          if (!eventFns) {
            eventFns = [];
            this.eventMap[eventName] = eventFns;
          }

          eventFns.push(eventFn);
        }
        emit(eventName, ...args) {
          const eventFns = this.eventMap[eventName];
          if (!eventFns) return;
          eventFns.forEach((fn) => {
            fn(...args);
          });
        }
        off(eventName, eventFn) {
          const eventFns = this.eventMap[eventName];
          if (!eventFns) {
            console.log("本来就没有这个eventName");
            return;
          }
          for (let i = 0; i < eventFns.length; i++) {
            const fn = eventFns[i];
            if (fn === eventFn) {
              eventFns.splice(i, 1);
              break;
            }
          }
          // 如果eventFns已经清空了
          if (eventFns.length === 0) {
            delete this.eventMap[eventName];
          }
        }
      }

      const eventBus = new EventBus();
      // aside.vue组件中监听事件
      eventBus.on("navclick", (name, age, height) => {
        console.log("navclick listener 01", name, age, height);
      });

      const click = () => {
        console.log("navclick listener 02");
      };
      eventBus.on("navclick", click);

      setTimeout(() => {
        eventBus.off("navclick", click);
      }, 5000);

      eventBus.on("asideclick", () => {
        console.log("asideclick listener");
      });

      // nav.vue
      const navBtnEl = document.querySelector(".nav-btn");
      navBtnEl.onclick = function () {
        console.log("自己监听到");
        eventBus.emit("navclick", "why", 18, 1.88);
      };
    </script>
  </body>
</html>

相关文章

  • RxJava实现事件总线(RxBus)学习笔记

    目录事件总线的介绍利用RxJava实现事件总线(Rxbus)Rxbus的使用 事件总线的介绍 1. 什么是事件总线...

  • 事件总线知多少(1)

    源码路径:Github-EventBus事件总线知多少(1)事件总线知多少(2) 1. 引言 事件总线这个概念对你...

  • 事件总线知多少(2)

    源码路径:Github-EventBus事件总线知多少(1)事件总线知多少(2) 1.引言 之前的一篇文章事件总线...

  • 使用JavaScript手写一个事件总线功能

    事件总线 事件总线主要是实现一些任意的或非父子关系的组件之间的数据通信 实现一个事件总线功能需要: 事件派发 $...

  • 走马观花 - EventBus

    EventBus是Android的中央发布/订阅事件系统。 事件被post到总线,总线将事件传递给具有事件类型的匹...

  • [大白装逼]YEventBus事件总线的实现

    Y事件总线:基于java的Observe和Observable实现的事件总线github地址:https://gi...

  • 事件总线

    Android应用开发中,经常会涉及Activity,Fragment,Service等不同组件或者模块之间的消息...

  • 事件总线

    EventBus 3.0进阶:源码及其设计模式 完全解析 EvenBus3.0用法介绍 Eventbus Squa...

  • 事件总线

    事件总线,提供了一个,解耦合,和异步的能力

  • 事件总线

    事件总线主要是为了解决组件间跨层级通信.

网友评论

      本文标题:事件总线

      本文链接:https://www.haomeiwen.com/subject/dryoartx.html