在Vue3+TypeScript 前端项目中使用事件总线Mitt

vue3,typescript,前端,项目,使用,事件,总线,mitt · 浏览次数 : 1364

小编点评

**使用 Mitt 进行 Vue 3+ TypeScript 事件处理** **简介** Mitt 是一个用于 Vue 3+ TypeScript 项目中事件处理的极简库。它提供了一些方便的函数,允许您轻松地监听事件并处理它们。 **优点** - 零依赖 - 体积超小,仅 200b - 支持 TypeScript,自动推断参数类型 - 基于闭包,没有烦人的 this - 支持所有浏览器,包括 IE9 **用法** 1. **安装 Mitt**: ``` npm install mitt ``` 2. **导入 Mitt**: ```typescript import mitt from 'mitt'; ``` 3. **创建事件监听器**: ```typescript const emitter = mitt(); ``` 4. **注册事件处理函数**: ```typescript emitter.on('event_name', function (eventData) { // 处理事件 }); ``` 5. **发布事件**: ```typescript emitter.emit('event_name', eventData); ``` **示例** ```typescript // 使用 Mitt 监听 'foo' 事件 import mitt from 'mitt'; const emitter = mitt(); emitter.on('foo', (event) => { console.log('foo', event); }); // 发布事件 emitter.emit('foo', 'hello world'); ``` **注意** - Mitt 需要在 Vue 项目中安装 `mitt` 组件。 - 您可以使用 `any` 类型来处理事件参数。 - Mitt 支持使用 TypeScript 的泛型。

正文

事件总线Mitt使用非常简单,本篇随笔介绍在Vue3+TypeScript 前端项目中使用的一些场景和思路。我们在Vue 的项目中,经常会通过emits 触发事件来通知组件或者页面进行相应的处理,不过我们使用事件总线Mitt来操作一些事件的处理,也是非常方便的。

Mitt 的GitHub官网地址如下所示:https://github.com/developit/mitt, 它的安装和其他插件一样,我们不再赘述,只讲述它的如何使用。

Mitt 具有以下优点:

  • 零依赖、体积超小,压缩后只有200b
  • 提供了完整的typescript支持,能自动推导出参数类型。
  • 基于闭包实现,没有烦人的this困扰。
  • 为浏览器编写但也支持其它javascript运行时,浏览器支持ie9+(需要引入Mappolyfill)。
  • 与框架无关,可以与任何框架搭配使用。
Mitt 只是提供了几个简单的方法,如on,off, emit 等基础的几个函数。
在JS中我们使用的话,不需要类型化事件的类型,如下代码所示。
import mitt from 'mitt'
const emitter = mitt()

// 订阅一个具体的事件
emitter.on('foo', e => console.log('foo', e) )

// 订阅所有事件
emitter.on('*', (type, e) => console.log(type, e) )

// 发布一个事件
emitter.emit('foo', { a: 'b' })

// 根据订阅的函数来取消订阅
function onFoo() {}
emitter.on('foo', onFoo)   // listen
emitter.off('foo', onFoo)  // unlisten

// 只传一个参数,取消订阅同名事件
emitter.off('foo')  // unlisten

// 取消所有事件
emitter.all.clear()

而我们如果在Vue3 + TypeScript 环境中使用的话,就需要类型化事件的类型,已达到强类型的处理目的。

import mitt from "mitt";

type Events = {
  foo: string;
  bar: number;
};

// 提供泛型参数让 emitter 能自动推断参数类型
const emitter = mitt<Events>();

// 'e' 被推断为string类型
emitter.on("foo", (e) => {
  console.log(e);
});

// ts error: 类型 string 的参数不能赋值给类型 'number' 的参数
emitter.emit("bar", "xx");

// ts error: otherEvent 不存在与 Events 的key中
emitter.on("otherEvent", () => {
  //
});

在前端项目使用的时候,我们在utils/mitt.ts中定义默认导出的mitt对象,如下代码所示。

// utils/mitt.ts

import mitt, { Emitter } from 'mitt';

// 类型
const emitter: Emitter<MittType> = mitt<MittType>();

// 导出
export default emitter;

在其中的MittType类型,可以单独文件放置TypeScript的预定义文件目录中,如types/mitt.d.ts

而我们在使用的时候,直接导入该对象就可以了,如下代码所示。

declare type MittType<T = any> = {
    openSetingsDrawer?: string;
    restoreDefault?: string;
    setSendColumnsChildren: T;

    .................. //省略其他事件类型

    noticeRead: number; // 消息已读事件
    lastAddParentId?: string | number;//新增记住最后的父信息
};

例如我们定义一个更新和记住父菜单的Mitt 事件,在页面加载完毕的时候监听事件,在页面退出的时候关闭事件即可,如下代码所示是在菜单列表页面中处理的。

<script lang="ts" setup name="sysMenu">
import { onMounted, onUnmounted, reactive, ref } from 'vue';
import mittBus from '/@/utils/mitt';
......
onMounted(async () => {
    handleQuery();

    mittBus.on('submitRefresh', () => {
        handleQuery();
    });
    mittBus.on('lastAddParentId', (pid) => {
        state.lastAddParentId = pid as string;//记住最后的父菜单ID
    });
});

onUnmounted(() => {
    mittBus.off('submitRefresh');
    mittBus.off('lastAddParentId');
});

</script>

在新增菜单的时候我们触发对应刷新事件 submitRefresh,以及触发选择的父记录ID的事件 lastAddParentId,这样就可以做相应的处理了。

例如在菜单的编辑子控件页面中,我们触发对应的事件逻辑代码如下所示。

// 关闭弹窗
const closeDialog = () => {
    mittBus.emit('submitRefresh');
    state.isShowDialog = false;
};

// 提交
const submit = () => {
    ruleFormRef.value.validate(async (valid: boolean) => {
        if (!valid) return;
        if (state.ruleForm.id != undefined && state.ruleForm.id > 0) {
            await menuApi.update(state.ruleForm);
        } else {
            await menuApi.add(state.ruleForm);
            //记住最后的菜单
            mittBus.emit('lastAddParentId', state.ruleForm.pid);
        }
        closeDialog();
    });
};

 如果为了减少每次重复的导入mitt,也可以把它全局挂载到变量中,统一入口进行访问,详细可以参考随笔《在基于vue-next-admin的Vue3+TypeScript前端项目中,为了使用方便全局挂载的对象接口》处理即可。

const $u: $u_interface = {
  message,
  test,
  util,
  date,
  crypto,
  base64,
  $t: i18n.global.t,
  fun: commonFunction(),

  cloneDeep,
  debounce,
  throttle,
  mitt
};

//安装$u组件到app上
import type { App } from 'vue';
export default {
  install(app: App<Element>) {
    // 挂载全局
    app.config.globalProperties.$u = $u;
  }
};

 

 

 

与在Vue3+TypeScript 前端项目中使用事件总线Mitt相似的内容:

在Vue3+TypeScript 前端项目中使用事件总线Mitt

事件总线Mitt使用非常简单,本篇随笔介绍在Vue3+TypeScript 前端项目中使用的一些场景和思路。我们在Vue 的项目中,经常会通过emits 触发事件来通知组件或者页面进行相应的处理,不过我们使用事件总线Mitt来操作一些事件的处理,也是非常方便的。

基于SqlSugar的开发框架循序渐进介绍(18)-- 基于代码生成工具Database2Sharp,快速生成Vue3+TypeScript的前端界面和Winform端界面

我们开发一个系统,在保证风格统一、代码强壮、可读性强等基础上,还能够结合代码生成工具快速开发相关后端,以及各种前端界面的,无疑是非常好的,既保证了项目的代码质量,又能够极大的提高开发效率。代码生成工具Database2Sharp是在完善的开发项目上,抽取出数据变化的部分,通过演绎、归纳、反复演绎和归纳等提炼方式抽取出相关的规则,以工具的方式来快速提高生产率,使得我们在开发各种不同的项目上的时候,能

在基于vue-next-admin的Vue3+TypeScript前端项目中,为了使用方便全局挂载对象接口

在基于vue-next-admin 的 Vue3+TypeScript 前端项目中,可以整合自己的 .NET 后端,前端操作一些功能的时候,为了使用方便全局挂载的对象接口,以便能够快速处理一些特殊的操作,如消息提示、辅助函数、正则测试等等。本篇随笔介绍在Vue3+TypeScript 前端项目中全局挂载对象$u,获得相关 $u_interface 的统一入口的接口信息。这样在组件或者页面中就可以方

基于SqlSugar的开发框架循序渐进介绍(22)-- Vue3+TypeScript的前端工作流模块中实现统一的表单编辑和表单详情查看处理

在工作流页面中,除了特定的业务表单信息外,往往也需要同时展示通用申请单的相关信息,因此在页面设计的时候需要使用一些组件化的概念来实现动态的内容展示处理,本篇随笔介绍Vue3+TypeScript+ElementPus的前端工作流模块中实现统一的表单编辑和表单详情查看处理。

详解Web应用安全系列(8)不足的日志记录和监控

在Web安全领域,不足的日志记录和监控是一个重要的安全隐患,它可能导致攻击者能够更隐蔽地进行攻击,同时增加了攻击被检测和响应的难度。以下是对Web攻击中不足的日志记录和监控漏洞的详细介绍。 一、日志记录不足的问题 日志缺失或不完整 关键操作未记录:如用户登录、敏感数据访问、系统管理员操作等关键操作未

光伏储能电厂设备连接iec61850平台解决方案

在当今日益发展的电力系统中,光伏储能技术以其独特的优势逐渐崭露头角,成为可再生能源领域的重要组成部分。而在光伏储能系统的运行与监控中,通信协议的选择与实现则显得至关重要。本文将重点介绍光伏储能系统中的Modbus协议、电力IEC 61850平台,以及如何通过协议转换网关实现Modbus转IEC 61

Qt实现汽车仪表盘

在UI界面显示中,仪表盘的应用相对比较广泛,经常用于显示速度值,电压电流值等等,最终实现效果如下动态图片(文末提供给源工程下载): 主要包含以下绘制步骤: 绘制画布 /* * 绘制画布 */ void Widget::initCanvas(QPainter &painter) { //消除锯齿 pa

Java定时任务实现优惠码

在Java中实现定时任务来发放优惠码,我们可以使用多种方法,比如使用java.util.Timer类、ScheduledExecutorService接口,或者更高级的框架如Spring的@Scheduled注解。这里,我将以ScheduledExecutorService为例来展示如何实现这一功能

对Transformer的一些理解

在学习Transformer这个模型前对seq2seq架构有个了解时很有必要的 先上图 输入和输出 首先理解模型时第一眼应该理解输入和输出最开始我就非常纠结 有一个Inputs,一个Outputs(shift right)和一个Output Probabilities,首先需要借助这三个输入/输出来

详解Web应用安全系列(5)敏感数据泄露漏洞

在最近几年,这是最常见的,最具影响力的攻击。这个领域最常见的漏洞是不对敏感数据进行加密。在数据加密过程中,常见的问题是不安全的密钥生成和管理以及使用弱密码算法,弱协议和弱密码。特别是使用弱的哈希算法来保护密码。在服务端,检测数据传输过程中的数据弱点很容易,但检测存储数据的弱点却非常困难。 敏感数据泄