手写实现简单的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]// 遍历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)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/470118.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

dhs手术是什么意思_#下颌角手术# #磨骨瘦脸# 下颌角手术多少钱?

不要一上来就问价格多少钱&#xff0c;有些人就留言说怕我这里手术太贵&#xff0c;前面问一圈其他问题都白问了。还有些人担心手术会因人定价&#xff0c;坐地起价之内的。其他地方我不知道&#xff0c;反正我能确保我这里价格标准都是一致的&#xff0c;下颌角总计30000-3500…

手写实现深拷贝函数

对象相互赋值的一些关系&#xff0c;分别包括&#xff1a; 引入的赋值&#xff1a;指向同一个对象&#xff0c;相互之间会影响&#xff1b;对象的浅拷贝&#xff1a;只是浅层的拷贝&#xff0c;内部引入对象时&#xff0c;依然会相互影响&#xff1b;对象的深拷贝&#xff1a;两…

第一款支持容器和云部署的开源数据库Neo4j 3.0

导读Neo4j 3.0.0 正式发布&#xff0c;这是 Neo4j 3.0 系列的第一个版本。此版本对内部架构进行了全新的设计&#xff1b;提供给开发者更强大的生产力&#xff1b;提供更广阔的部署选择。Neo4j 3.0 被认为是世界上最具伸缩性的基于Java的图片数据库。Neo4j 3.0.0 主要的新特性&…

八皇后解法(回溯法)

package com.company;/** * Created by Administrator on 2016/9/15. */public class EigthQueue { private static int N 8; private int count 0; // 总方案数 private int[] flag {-1, -1, -1, -1, -1, -1, -1, -1}; //回溯法递归实现八皇后问题 //输出棋…

手写防抖和节流函数

一、认识防抖debounce函数 我们用一副图来理解一下它的过程&#xff1a; 当事件触发时&#xff0c;相应的函数并不会立即触发&#xff0c;而是会等待一定的时间&#xff1b;当事件密集触发时&#xff0c;函数的触发会被频繁的推迟&#xff1b;只有等待了一段时间也没有事件触…

中webgl解析json_WebGL蒙皮(下)

今天继续学习webgl一个重要功能&#xff1a;skinning(蒙皮)&#xff0c;内容来自学习网站webglfundamentals&#xff0c;这里仅供学习交流&#xff0c;原文链接&#xff1a;https://webglfundamentals.org/webgl/lessons/zh_cn/webgl-skinning.html。文章并非原创&#xff01;如…

Vue权限控制——动态注册路由

需求&#xff1a;实现后台管理系统不同用户的权限控制 根据登录的用户的角色动态展示后台管理系统的左侧菜单栏的菜单列表内容&#xff0c;然后还要动态注册对应子菜单的路由 菜单列表内容应该通过后端接口返回&#xff1a; sort为1表示当前项有子菜单sort为2表示当前项没有子…

react不同环境不同配置angular_前端问题集:vue配置环境-给不同的环境配不同的打包命令...

通过vue-cli脚手架构建出一个前端项目&#xff0c;通过npm run build打包&#xff0c;发布到线上&#xff0c;但是这样做需要每次都手动修改接口地址。我们可以通过自行配置打包命令实现无需修改接口地址&#xff0c;打各个环境的包。文档结构大致如下图&#xff1a;1.找到conf…

使用PLSql连接Oracle时报错ORA-12541: TNS: 无监听程序

今天用plsql连接oracle的时候报了无监听程序&#xff0c;寻思是plsql的问题&#xff0c;可惜重装了也没什么卵用&#xff0c;才把注意力集中到oracle服务上&#xff0c;啥也不说了&#xff0c; 直接上链接&#xff1a; 使用PLSql连接Oracle时报错ORA-12541: TNS: 无监听程序转载…

基于Element-plus封装配置化表单组件(组件的v-model实现)

一、预备知识 1.1 组件的v-model 前面我们在input中可以使用v-model来完成双向绑定&#xff1a; 这个时候往往会非常方便&#xff0c;因为v-model默认帮助我们完成了两件事&#xff1b;v-bind:value的数据绑定 和 input的事件监听&#xff1b; 如果我们现在封装了一个组件…

Scala IDE for Eclipse的下载、安装和WordCount的初步使用(本地模式和集群模式)

不多说&#xff0c;直接上干货&#xff01; 这篇博客是&#xff0c; 是在Scala IDEA for Eclipse里maven创建scala和java代码编写环境。 Scala IDEA for Eclipse里用maven来创建scala和java项目代码环境&#xff08;图文详解&#xff09; 本博文包括&#xff1a; Scala IDE fo…

笔记本AutoCAD启动时闪退怎么办_戴尔笔记本电脑开不了机如何解决【解决方法】...

生活在互联时代下&#xff0c;我们对笔记本的需求是无处不在的&#xff0c;不管是上班族还是学生党&#xff0c;使用笔记本办公和学习给我们的生活带来很大的便捷。但使用的过程中&#xff0c;总有可能会遇到无法预料的问题。比方说 笔记本电脑 无法开机的问题&#xff0c;当…

JS高级——函数执行、作用域链内存结构图

一、JavaScript的执行过程 假如我们有下面一段代码&#xff0c;它在JavaScript中是如何被执行的呢&#xff1f; 1.1 第一步&#xff1a;初始化全局对象 js引擎会在执行代码之前&#xff0c;会在堆内存中创建一个全局对象&#xff1a;Global Object&#xff08;GO&#xff09…

两个队列+k叉哈夫曼树 HDU 5884

1 // 两个队列k叉哈夫曼树 HDU 58842 // camp题解&#xff1a;3 // 题意&#xff1a;nn个有序序列的归并排序.每次可以选择不超过kk个序列进行合并,合并代价为这些序列的长度和.总的合并代价不能超过TT, 问kk最小是多少。4 // .5 // 题解&#xff1a;首先二分一下这个kk。然后在…

JS高级——内存管理和闭包

0、预备知识 0.1 认识内存管理 不管什么样的编程语言&#xff0c;在代码的执行过程中都是需要给它分配内存的&#xff0c;不同的是某些编程语言需要我们自己手动的管理内存&#xff0c;某些编程语言会可以自动帮助我们管理内存&#xff1a; 不管以什么样的方式来管理内存&…

Google-优秀移动站点设计10招

Google-优秀移动网站设计10招 1&#xff09;添加一个醒目的搜索条&#xff1a;在移动终端上&#xff0c;人们希望能够快速找到自己需要的东西 2&#xff09;把大表格拆分成小块&#xff1a;别搞一个长长的表格页面&#xff0c;上面包含各种输入框 3&#xff09;允许用户匿名浏览…

div超出不换行_div+CSS设置一行内文字超过宽度不换行且不显示

当一行文字超过DIV或者Table的宽度的时候&#xff0c;浏览器中默认是让它换行显示的&#xff0c;如果我们不想让他换行显示那要怎么办呢&#xff1f;看到这个标题很容易就会想到截断文字加“...”的做法。一般的文字截断(适用于内联与块)&#xff1a;CSS.text-overflow{display…

Angular2学习笔记——在子组件中拿到路由参数

工作中碰到的问题&#xff0c;特此记录一下。 Angular2中允许我们以path\:id\childPath的形式来定义路由&#xff0c;比如&#xff1a; export const appRoutes: RouterConfig [{path: app/:id, component: AppComponent,children: [{ path: share, component: AppShareCompon…

提取多个字段_【博客翻译】建筑物轮廓线提取以及损坏分类

原文链接原作者&#xff1a;Rohit Singh, Sandeep Kumar贡献者&#xff1a;Vinay Viswambharan, Divyansh Jha, Shivani Pathak, Daniel Wilson.翻译&#xff1a;荆雪涵在今年的 Esri 用户大会上&#xff0c;USAA 展示了基于 ArcGIS 深度学习能力&#xff0c;对 Woolsey 火灾进…

读取外部配置文件_SpringBoot外部配置、优先级及配置详解

一、外部配置及优先级SpringBoot的外部配置属性值官方给出了很多种方式&#xff0c;以便可以在不同的环境中使用相同的代码。其使用了非常特别的PropertySource命令&#xff0c;旨在允许合理的覆盖值。当然&#xff0c;如果属性值不同&#xff0c;则这些配置方式中的属性值都会…