手写事件总线 EventBus

本文介绍了EventBus的工作原理,它作为一个事件总线,通过任务队列管理事件的订阅、发布和取消订阅。核心方法包括on(订阅)、once(一次性订阅)、emit(发布)和off(取消订阅)。示例代码展示了如何实现这些功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

EventBus 简化了各个组件之间进行通信的复杂度,其工作原理在于对事件的监听与手动触发:
作为一个事件总线,它应当具备一个任务队列,以及三个方法:订阅方法、发布方法、取消订阅

上代码

class EventBus {
  constructor() {
    this.tasks = {}; // 按事件名称创建任务队列
  }

  /**
   * 注册事件(订阅)
   * @param {String} type  事件名称
   * @param {Function} fn  回调函数
   */
  on(type, fn) {
    // 如果还没有注册过该事件,则创建对应事件的队列
    if (!this.tasks[type]) {
      this.tasks[type] = [];
    }
    // 将回调函数加入队列
    this.tasks[type].push(fn);
  }
  
  /**
   * 注册一个只能执行一次的事件
   * @params type[String] 事件类型
   * @params fn[Function] 回调函数
   */
  once(type, fn) {
    if (!this.tasks[type]) {
      this.tasks[type] = [];
    }

    const that = this;
    // 注意该函数必须是具名函数,因为需要删除,但该名称只在函数内部有效
    function _once(...args) {
      fn(...args);
      that.off(type, _once); // 执行一次后注销
    }

    this.tasks[type].push(_once);
  }

  /**
   * 触发事件(发布)
   * @param {String} type  事件名称
   * @param {...any} args  传入的参数,不限个数
   */
  emit(type, ...args) {
    // 如果该事件没有被注册,则返回
    if (!this.tasks[type]) {
      return;
    }
    // 遍历执行对应的回调数组,并传入参数
    this.tasks[type].forEach((fn) => fn(...args));
  }

  /**
   * 移除指定回调(取消订阅)
   * @param {String} type  事件名称
   * @param {Function} fn  回调函数
   */
  off(type, fn) {
    const tasks = this.tasks[type];
    // 校验事件队列是否存在
    if (!Array.isArray(tasks)) {
      return;
    }

    // 利用 filter 删除队列中的指定函数
    this.tasks[type] = tasks.filter((cb) => fn !== cb);
  }
}
Vue的事件总线是一种在组件之间进行通信的机制,它允许一个组件触发事件并让其他组件监听和响应这些事件。如果你想手写一个简单的Vue事件总线,可以按照以下步骤进行: 1. 创建一个新的Vue实例作为事件总线: ```javascript // eventBus.js import Vue from 'vue'; const eventBus = new Vue(); export default eventBus; ``` 2. 在需要通信的组件中,导入事件总线并使用它: ```javascript // ComponentA.vue import eventBus from './eventBus'; export default { methods: { handleClick() { // 触发自定义事件,并传递数据 eventBus.$emit('customEvent', data); } } } ``` 3. 在需要监听事件的组件中,导入事件总线并使用它: ```javascript // ComponentB.vue import eventBus from './eventBus'; export default { created() { // 监听自定义事件 eventBus.$on('customEvent', this.handleCustomEvent); }, destroyed() { // 在组件销毁时取消事件监听 eventBus.$off('customEvent', this.handleCustomEvent); }, methods: { handleCustomEvent(data) { // 处理接收到的数据 } } } ``` 通过以上步骤,你就可以手写一个简单的Vue事件总线。在需要通信的组件中,使用`eventBus.$emit`来触发自定义事件,并可以传递数据;在需要监听事件的组件中,使用`eventBus.$on`来监听自定义事件,并在事件触发时执行相应的处理函数。记得在组件销毁时使用`eventBus.$off`来取消事件监听,以避免内存泄漏。 请注意,手写的Vue事件总线是一个简单的实现,它没有考虑到一些高级功能,如命名空间、多个事件总线实例等。如果需要更复杂的功能,可以考虑使用第三方插件或使用Vuex进行状态管理。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值