• 模拟事件总线


    事件总线

    前言: 单页面应用,页面不刷新,页面定义的变量和函数是一直保持的。
    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

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

  • 相关阅读:
    TDengineGUI无法连接TDengine
    JNDI注入的理解、JDK给出的修复
    21. CSS 优化和提高性能的方法有哪些?
    java反射所需要了解的基本知识点
    RPC接口测试技术-Tcp 协议的接口测试
    IP地址在网络安全中的关键作用
    算法2:链表的逆转
    炫酷登录注册界面【超级简单 jQuery+JS+HTML+CSS实现】
    LeetCode99之恢复二叉搜索树(相关话题:中序遍历)
    C语言航路外传之隐式转换与优先级的那点事(你程序总是出bug的一个重要原因)
  • 原文地址:https://blog.csdn.net/qq_52440306/article/details/126609352