一、什么是事件总线

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

  • 发布者(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]// 遍历newHandlersfor (let i = 0; i < newHandlers.length; i++) {// 获取newHandlers中的每个handlerconst 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事件总线相关推荐

  1. 深入了解Vue 2响应式原理,并手写一个简单的Vue

    1. Vue 2的响应式原理 Vue.js 一个核心思想是数据驱动.所谓数据驱动是指视图是由数据驱动生成的,对视图的修改,不会直接操作 DOM,而是通过修改数据.vue.js里面只需要改变数据,Vue ...

  2. jquery手写轮播图_用jQuery如何手写一个简单的轮播图?(附代码)

    用jQuery如何手写一个简单的轮播图?下面本篇文章通过代码示例来给大家介绍一下.有一定的参考价值,有需要的朋友可以参考一下,希望对大家有所帮助. 用 jQuery 手写轮播图 先上个效果截图: 主要 ...

  3. 手写实现简单栈(练习题)

    一.手写实现简单栈 push(x) -- 将元素 x 推入栈中. pop() -- 删除栈顶的元素. top() -- 获取栈顶元素. getMin() -- 检索栈中的最小元素.示例:输入: [&q ...

  4. 手写一个简单的IOC容器

    手写一个简单的IOC容器 原文 http://localhost:4000/2020/02/25/SSM/spring/%E6%89%8B%E5%86%99%E4%B8%80%E4%B8%AA%E5% ...

  5. 怎么手写一个简单的List集合

    List集合 手写一个简单的List集合为自己调用并不是特别难,只需要定义一个集合接口去提供所有方法的定义如下代码 : package com.myself.util; /*** * @author ...

  6. 基于bio手写实现简单的rpc

    基于bio手写实现简单的rpc 1.bio基础知识 Java BIO:传统的网络通讯模型,就是BIO,同步阻塞IO, 其实就是服务端创建一个ServerSocket, 然后就是客户端用一个Socket ...

  7. vue 事件总线EventBus的概念、使用以及注意点

    vue组件中的数据传递最最常见的就是父子组件之间的传递.父传子通过props向下传递数据给子组件:子传父通过$emit发送事件,并携带数据给父组件.而有时两个组件之间毫无关系,或者他们之间的结构复杂, ...

  8. vue事件总线_[面试] 聊聊你对 Vue.js 框架的理解

    作者:yacan8 https://github.com/yacan8/blog/issues/26 本文为一次前端技术分享的演讲稿,所以尽力不贴 Vue.js 的源码,因为贴代码在实际分享中,比较枯 ...

  9. 小白前端之路:手写一个简单的vue-router这几年,好像过的好快,怀念我的大学生活。 - 连某人 大三实习生,之前写过简单MVVM框架、简单的vuex、但是看了vue-router的源码(看了

    这几年,好像过的好快,怀念我的大学生活. 连某人 大三实习生,之前写过简单MVVM框架.简单的vuex.但是看了vue-router的源码(看了大概)之后就没有写,趁着周末不用工作(大三趁着不开学出来 ...

最新文章

  1. 12层也能媲美ResNet?YOLOv4一作邓嘉团队提出ParNet:非深度网络!
  2. 常见问题_数组索引越界异常
  3. 告别求职难!一汽-大众专场直播招聘来了
  4. 单招考试计算机专业大概分数线是多少,单招分数线一般多少?
  5. CSS进阶(4)—— 温和padding中的诡异CSS现象
  6. 现浇板用弹性计算方法_自建房砖混结构现浇楼板配筋的要求和计算方法
  7. 43.访问控制过滤器(Access Control Filter)
  8. MapXtreme 2005 学习心得 了解新建MapXtreme项目结构(二)
  9. Spring Cloud Alibaba Nacos集群和持久化配置
  10. win32汇编实现一个时钟
  11. 关于onpropertychange与oninput的兼容问题
  12. 伍斯特理工学院计算机,世界排名领先,伍斯特理工学院到底有多厉害?
  13. linux解锁文件夹
  14. hacking 麦步手表之(3)制作一个英文表盘xzy-reborn
  15. 新时达工业机器人技术储备_国内外工业机器人发展现状-工业机器人技术国内外发展现状与趋势...
  16. 影评系统的机遇和挑战
  17. 马云的江湖 史玉柱的兵法
  18. 【AI学习总结】均方误差(Mean Square Error,MSE)与交叉熵(Cross Entropy,CE)损失函数
  19. python画恐龙_Python
  20. firefox linux 中文字体,Ubuntu下的Firefox字体配置方案

热门文章

  1. c语言的翻译叫什么_什么是编译器?什么是集成开发环境?
  2. linux驱动 自旋锁
  3. const修饰指针和引用的用法【转贴】
  4. java compliance_java complier compliance level问题引发的思考
  5. PHP通过session判断防止表单重复提交实例
  6. 关于z-index的一些问题
  7. 最近做项目的一些关于重构方面的总结
  8. MySQL Server Architecture
  9. 行向量,列向量,行主序矩阵,列主序矩阵
  10. 胃部不适,原来好辛苦!