• 模拟事件总线


    事件总线

    前言: 单页面应用,页面不刷新,页面定义的变量和函数是一直保持的。
    vue中的全局事件总线,是把触发的回调方法挂到了vue全局变量上。先监听,然后在需要的地方触发。因为全局变量,子孙组件通过引用都可以访问到。
    简单理解为,提前把要触发方法先保存起来,在使用的地方传参调用

    模拟过程

    先定义一个类,初始化保存我们要执行的函数

    		class Bus{
    			constructor(){
    				this.eventPool = {};
    			};
    		};
    
    • 1
    • 2
    • 3
    • 4
    • 5

    模式实现 $on 方法,将监听的函数保存到 eventPool 属性上

    			on(eventName, cd){
    				if ( typeof cd === 'function'){
    					this.eventPool[eventName] = cd;
    					console.log('监听了一个事件:', eventName);
    				} else {
    					console.log('请设置监听回调函数');
    				}
    			};
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    模拟实现 off 方法, 删除之前保存的函数

    			off(...argem){
    				Array.from(argem).forEach((eventName) => {
    					delete this.eventPool[eventName];
    					console.log('卸载了一个事件:', eventName);
    				});
    			};
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    模拟实现 emit 方法,这个方法就是触发器,通过指定的函数名去找应的函数执行,同时将参数传递过去。

    			emit(...agemt){
    			   const eventName = agemt[0];
    			   const cd = this.eventPool[eventName];
    			   const paramenter = agemt.slice(1);
    			   if (typeof cd === 'function') {
    				   cd(...paramenter);
    				   console.log('触发了一个事件:', eventName);
    			   };
    			};
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    基本实现了,测试一下。

    		const myBus = new Bus();
    		myBus.on('loading', (res) => {
    			console.log(res);
    		})
    		myBus.on('loadEnd', (res) => {
    			console.log(res);
    		})
    		setTimeout(() => {
    			myBus.emit('loading', '数据加载中');
    			setTimeout(() => {
    				myBus.emit('loadEnd', '数据加载完毕');
    				myBus.off('loading', 'loadEnd');
    			}, 2000)
    		}, 2000);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    测试结果与预期相同
    在这里插入图片描述

    实现代码

    		class Bus{
    			constructor(){
    				this.eventPool = {};
    			}
    			on(eventName, cd){
    				if ( typeof cd === 'function'){
    					this.eventPool[eventName] = cd;
    					console.log('监听了一个事件:', eventName);
    				} else {
    					console.log('请设置监听回调');
    				}
    			};
    			off(...argem){
    				Array.from(argem).forEach((eventName) => {
    					delete this.eventPool[eventName];
    					console.log('卸载了一个事件:', eventName);
    				})
    			}
    			emit(...agemt){
    			   const eventName = agemt[0];
    			   const cd = this.eventPool[eventName];
    			   const paramenter = agemt.slice(1);
    			   if (typeof cd === 'function') {
    				   cd(...paramenter);
    				   console.log('触发了一个事件:', eventName);
    			   }
    			}
    		}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    总结: 在框架中要比这复杂的多,如果项目庞大,对于事件的命名,可以更据场景命名。避免冲突。

  • 相关阅读:
    CSRF / XSRF(跨站请求伪造),XSS/CSS(跨站脚本攻击)
    C++容器工作效率-内存操作
    卷土重来?东山再起?不,C语言一直是王者
    Python 批量修改文件名
    学习开发一个RISC-V上的操作系统(汪辰老师) — 一次RV32I加法指令的反汇编
    【C++】——类与对象引入和认识
    使用Kubernetes和Docker部署Java微服务
    极简OpenFoam编程
    服务器宕机了,Kafka 消息会丢失吗?
    如何使用Goland进行远程Go项目线上调试?
  • 原文地址:https://blog.csdn.net/qq_52440306/article/details/126609352