JS实现 Event Bus

利用ES6的class关键字对Event进行初始化,包括Event的事件清单和监听者上限.

选择Map作为储存事件的结构,因为作为键值对的储存方式Map比一般对象更加适合,操作起来也更加简洁

class EventBus {
    constructor () {
        this._events = this._events || new Map(); // 存储事件/回调键值对
        this._maxListeners = this._maxListeners || 10; // 设立监听上限
    }

    // $on 监听    
    on(type,fn) {
        const handler = this._events.get(type); // 获取对应事件名称的函数清单
        if (!handler) {
            this._events.set(type, fn);
        } else if (handler && typeof handler === 'function') {
            // 如果handler是函数,说明当前只有一个监听者
            // 再次添加监听者,需要改用 数组储存
            this._events.set(type,[handler,fn]);
        } else {
            // 已有多个监听者,直接往数组里push函数即可
            handler.push(fn);
        }
    }

    // $emit 触发
    emit(type, ...args) {
        let handler = this._events.get(type);

        if (Array.isArray(handler)) {
            // 是数组,说明有多个监听者,需要依次触发里边的函数
            for (let i=0;i<handler.length;++i) {
                if (args.length > 0) {
                    handler[i].apply(this,args);
                } else {
                    handler[i].call(this);
                }
            }
        } else {
            // 单个函数的情况直接触发即可
            if (args.length > 0) {
                handler.apply(this,args);
            } else {
                handler.call(this);
            }
        }

        return true
    }

    // $off 移除监听 (此处跟原文相比略有改动)
    off(type,fn) {
        const handler = this._events.get(type);

        if (handler && typeof handler === 'function') {
            // 函数,说明只有一个监听者,直接删除就行
            this._events.delete(type,fn)
        } else {
            handler.splice(handler.findIndex(e => e === fn), 1);
        }
    }
}



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Vue.js 中,Event Bus 是一种用于在组件之间进行通信的模式,它可以实现组件间的数据共享。 Event Bus 是一个全局的 Vue 实例,它可以作为中央事件总线来传递事件和数据。可以使用 Vue 的 `prototype` 属性来定义一个全局的 Event Bus,例如: ```js // 定义全局的 Event Bus Vue.prototype.$bus = new Vue() // 在组件中使用 Event Bus this.$bus.$emit('event-name', data) this.$bus.$on('event-name', handler) ``` 在上面的例子中,定义了一个全局的 Event Bus,并使用 `$emit` 方法来触发一个自定义事件,并传递数据 `data` 给事件处理函数。同时,使用 `$on` 方法来监听这个自定义事件,并指定一个事件处理函数 `handler` 来处理事件。 可以在多个组件中使用 Event Bus实现数据共享,例如: ```js // 组件 A this.$bus.$emit('update-name', 'new name') // 组件 B this.$bus.$on('update-name', function(name) { this.name = name }) ``` 在上面的例子中,组件 A 使用 Event Bus 触发一个名为 `update-name` 的自定义事件,并传递一个新的名字 `'new name'`。组件 B 监听这个事件,并在事件处理函数中将 `name` 属性更新为新的名字。 需要注意的是,使用 Event Bus 可以实现组件之间的数据共享,但也容易造成代码的混乱和难以维护。因此,在使用 Event Bus 时,应该遵循一些规范和最佳实践,例如: - 明确事件的名称和数据类型,以避免出现名称冲突和数据类型不一致的问题。 - 在组件销毁时,应该及时取消对事件的监听,以避免内存泄漏。 - 不要滥用 Event Bus,应该使用其他更合适的方式(如 Vuex)来进行数据共享。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

前端卡卡西呀

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值