• vue3/vue2的兄弟组件的传值


    说到兄弟组件之间的传值你会想到什么?

    用兄弟A传给父组件再由父组件传给兄弟B,可以,但是太繁琐了。
    vuex可以简化,跳过了父组件的层层相传,但是有的简单的传值还没有必要用vuex。

    Vue2.x 使用 EventBus 事件总线进行兄弟组件通信,而在Vue3中事件总线模式已经被移除,而官方建议使用外部的、实现了事件触发器接口的库,例如 mitt。

    mitt 的优点:
    • 体积小,网上流传只有200bytes(我打开看有349b,也是挺小了)
    • 支持全部事件的监听和批量删除
    • 不依赖于vue实例,可以用到react或者jquery上去

    所以,大胆开心地开始使用吧!

    一、如何使用?

    下面我以vue中使用为例:

    1. 安装
    npm install --save mitt
    
    • 1
    1. 创建一个js文件 比如 utils/bus.js
    import mitt from 'mitt'
    const emiiter = mitt()
    export default emiiter
    
    • 1
    • 2
    • 3
    1. 在兄弟PageA中发布事件:
    import emitter from '@/utils/bus'
    import { ref } from 'vue'
    const Aname= ref('我是小虾') 
    emitter.emit('handleEvent', Aname)
    
    • 1
    • 2
    • 3
    • 4
    1. 在兄弟PageB中监听事件,并在组件销毁时取消监听
    import emiiter from '@/utils/bus'
    import { ref, onBeforeMount, onUnmounted } from 'vue'
    const Bname= ref('') // 等待接收
    const handelEventFn1 = (Aname)=>{
     Bname.value = Aname.value
     }
    
    
    onBeforeMount(() => {
      emiiter.on('handleEvent',handelEventFn1)  // 开启监听,监听到handleEvent事件后,执行handelEventFn1函数,当然你也可以在另外的页面监听handleEvent事件去执行handelEventFn2
    })
    onUnmounted(() => {
      emiiter.off('handleEvent',handelEventFn) //  取消handleEvent事件的handelEventFn函数监听
      emiiter.off('handleEvent') //  取消handleEvent事件的全部处理函数的监听
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    二、mitt源码解读:

    mitt是用new Map()作为整体的事件处理中心的
    而JavaScript的对象(Object),本质上是键值对的集合(Hash结构),但是传统上只能用字符串当作键。这给它的使用带来了很大的限制。
    为了解决这个问题,ES6提供了Map数据结构。它类似于对象,也是键值对的集合,但是“键”的范围不限于字符串,各种类型的值(包括对象)都可以当作键。

    exports.__esModule = true;
    function mitt(all) {
    	// 声明一个Map类型,作为整体事件处理中心
    	all = all || new Map(); // Map类型是键值对的有序列表,而键和值都可以是任意类型
    	return {
    		all,
    		on (type, handler) {
    			// 先读取是否有对应事件的处理函数数组
    			let handlers = all.get(type);
    			if (handlers) {
    				// 将新注册的函数推送到对应时间的函数数组中(发布一个事件,可以承载多个函数)
    				handlers.push(handler);
    			}
    			else {
    				// 创建一个对应 type 的函数数组
    				all.set(type, [handler]);
    			}
    		},
    		off (type, handler) {
    			// 从map中取出所有的对应的函数数组
    			let handlers = all.get(type);
    			if (handlers) {
    				// 如果存在hanlder,进行筛选后,从数组中删除。
    				// 如果不存在直接清空当前事件所有的处理函数
    				if (handler) {
    					handlers.splice(handlers.indexOf(handler) >>> 0, 1);
    				}
    				else {
    					all.set(type, []);
    				}
    			}
    		},
    		emit (type, evt) {
    			let handlers = all.get(type);
    			// 按照取出的函数数组遍历循环执行
    			if (handlers) {
    				handlers
    					.slice()
    					.map((handler) => {
    						handler(evt);
    					});
    			}
    			// 如果注册了 "*" 的事件,执行它
    			handlers = all.get('*');
    			if (handlers) {
    				handlers
    					.slice()
    					.map((handler) => {
    						handler(type, evt);
    					});
    			}
    		}
    	};
    }
    exports.default = mitt;
    
    
    • 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
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56

    使用mitt又简单又方便的解决了组件之间传值的问题。

    下面我附上mitt 的git连接:
    https://www.npmjs.com/package/mitt

  • 相关阅读:
    JDBC教程
    多实例安装 mysql 5.7
    Tuxera NTFS2022Mac驱动完美支持NTFS硬盘读写
    RabbitMQ的工作模式——WorkQueues
    数据库的范式
    react是否支持给标签设置自定义的属性,比如给video标签设置webkit-playsinline?
    Xilinx FPGA 7系列 GTX/GTH Transceivers (3) Aurora 8b10b
    CSS保持宽高比(aspect-ratio)VS(padding-top)
    腾讯云2023年双11优惠活动和9999元代金券领取规则
    SR660 V2 ESXI 的安装
  • 原文地址:https://blog.csdn.net/u010463466/article/details/126877872