vue3集成Mitt发布订阅库

news/2025/1/2 0:01:00/

先从git上扒来一段话介绍一下mitt这个库:

Mitt是一个小巧的JavaScript发布-订阅库,用于在应用程序中实现事件监听和触发。

它只有70行代码,并支持ES模块、CommonJS和UMD等多种模块化规范。使用Mitt,您可以轻松地将消息传递给订阅者,从而实现组件之间的通信和功能扩展。该库非常灵活且易于使用,可帮助您优化项目的结构和性能。

在项目开发中经常会遇到组件之间互相通信,如父子兄弟之间。之前一直用$emit绑定方法,很麻烦而且还有局限性。然而mitt提供的发布订阅模式,可以全局监听并且使用简洁易懂。

介绍一下它的几个方法:

  • on:订阅一个事件。

  • off:根据给定的名称,取消订阅事件。

  • emit:触发订阅事件的方法。

下面进入实战:

1.先安装一下mitt

npm install -S mitt

2. 在src下创建plugins目录,并新建mybus.js,然后按照如下进行实例化导出

import mitt from 'mitt'
export default mitt()

3. 在进行发布订阅的组件中导入mitt,主要就是send方法中的

mitt.emit("fun", {

data:"data"

});

第一个参数是发布事件名称,第二个参数是要发布的数据。

解释一下我为什么这里用了setTimeout。因为有的业务场景,目标组件是不显示的,此时v-if=false,所以目标组件就无法监听订阅事件。

所以这里分开执行,当我需要发布的时候,先把组件显示出来,然后再进行事件发布。

<template><h2>组件A</h2><button @click="send">发送消息</button><B v-if="show"></B>
</template>
import {reactive, toRefs, watch, getCurrentInstance, onMounted} from "vue"
import mitt from "@/plugins/mybus"
import B from '@/views/b.vue'
export default {name: "a",components:{B},setup(props, {emit}) {const state = reactive({show:false})const send = ()=>{state.show=true;setTimeout(function(){mitt.emit("fun", {data:"data"});})}onMounted(() => {})return {...toRefs(state),send}}}

4. 目标组件进行订阅,这里的监听主要就是

mitt.on('fun',(data)=>{

console.log("B接收到A的数据:",data)

});

使用mitt的on方法来订阅事件,第一个参数是事件名称,第二个参数是回调方法,回调参数就是发布的数据

import {reactive, toRefs, watch, getCurrentInstance, onMounted} from "vue"
import mitt from "@/plugins/mybus"
export default {name: "b",setup(props, {emit}) {onMounted(() => {mitt.on('fun',(data)=>{console.log("B接收到A的数据:",data)});})}}

我想大部分同志都是为了解决问题才看到的这篇文章,为了不占用感情,所以把原理解析放到了最后

可以看下源码

function mitt(all) {// 声明一个Map类型,作为整体事件处理中心all = all || new 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;

其实核心思想就是用一个map来储存事件,订阅的时候根据key来找到对应的方法。


http://www.ppmy.cn/news/32479.html

相关文章

【华为OD机试真题 JAVA】TLV编码问题

标题:TLV编码问题 | 时间限制:1秒 | 内存限制:262144K | 语言限制:不限 TLV编码是按TagLengthValue格式进行编码的,一段码流中的信元用tag标识,tag在码流中唯一不重复,length表示信元value的长度,value表示信元的值,码流以某信元的tag开头,tag固定占一个字节,lengt…

C/C++每日一练(20230314)

目录 1. 移动数组中的元素 2. 搜索二维矩阵 3. 三角形最小路径和 &#x1f31f; 每日一练刷题专栏 &#x1f31f; Golang 每日一练 专栏 C/C 每日一练 ​专栏 Python 每日一练 专栏 Java 每日一练 专栏 1. 移动数组中的元素 将一维数组中的元素循环左移 k 个位置 输入…

UE笔记-AI Move To无法正常结束/打断 1

启用Stop on Overlap 会导致AI与目标距离受到碰撞影响&#xff0c;实际效果需按要求处理 当Lock AILogic为True时&#xff0c;Move To的Task无法被黑板装饰器打断 当Use Continuos Goal Tracking为True时&#xff0c;Move To的节点不会根据Acceptance Radius设定而结束&#x…

SerializationException: Could not read JSON: Unrecognized field

org.springframework.data.redis.serializer.SerializationException: Could not read JSON: Unrecognized field原因&#xff1a;对象中如果有setXXX或getXXX方法&#xff0c;或返回值为Boolean或boolean的isXXX方法&#xff0c;但没有对应的XXX字段&#xff0c;使用Jackson2J…

RK3568在Android上进行驱动模块开发(源码外)

文章目录 前言一、ARCH架构二、编译器三、建立自己的Makefile文件总结前言 本文记录在驱动开发时,由于编译内核时间较长,经常会选择单独编译一个模块,这里主要讲解,makefile文件如何编写(主要是编译器和架构) 提示:以下是本篇文章正文内容,下面案例可供参考 一、ARCH…

血泪经验总结,财务会计人员面试指南

为什么每次面试都会很慌&#xff1f;一紧张就大脑一片空白&#xff0c;前言不搭后语&#xff0c;被问得一愣一愣的&#xff0c;尴尬得脚趾能把鞋底扣穿。只能说太年轻了&#xff0c;老练的应聘者都是反客为主把面试官问得赶紧把老板请来的。要避免面试紧张失常发挥的局面&#…

Visual Studio Code 1.76 发布

欢迎使用 Visual Studio Code 2023 年 2 月版&#xff0c;其中一些亮点包括&#xff1a; 配置文件 - 活动配置文件徽章&#xff0c;通过命令面板快速切换配置文件。辅助功能改进 - 新的音频提示&#xff0c;改进的终端屏幕阅读器模式。可移动的 Explorer 视图- 将资源管理器放…

IDEA常用插件列表

一 背景 IDEA常用插件列表&#xff0c;用来提供工作效率。你都安装了吗 IntelliJ IDEA 默认安装并提供了非常多的工具&#xff0c;比如 Maven Integration、Markdown support、SSH Remote Run 等。其中有很多好用&#xff0c;但是不为人知的工具。 二 插件列表 阿里代码规约…