首页IT科技vue图标选择器(在Vue3+TypeScript 前端项目中使用事件总线Mitt)

vue图标选择器(在Vue3+TypeScript 前端项目中使用事件总线Mitt)

时间2025-08-04 19:01:46分类IT科技浏览6475
导读:事件总线Mitt使用非常简单,本篇随笔介绍在Vue3+TypeScript 前端项目中使用的一些场景和思路。我们在Vue 的项目中,经常会通过emits触发事件来通知组件或者页面进行相应的处理,不过我们使用事件总线Mitt来操作一些事件的处理,也是非常方便的。...

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

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

Mitt具有以下优点:

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; } };
声明:本站所有文章                    ,如无特殊说明或标注                        ,均为本站原创发布。任何个人或组织    ,在未征得本站同意时                ,禁止复制                、盗用                        、采集        、发布本站内容到任何网站            、书籍等各类媒体平台                    。如若本站内容侵犯了原著者的合法权益                        ,可联系我们进行处理                        。

创心域SEO版权声明:以上内容作者已申请原创保护,未经允许不得转载,侵权必究!授权事宜、对本内容有异议或投诉,敬请联系网站管理员,我们将尽快回复您,谢谢合作!

展开全文READ MORE
苹果cms视频教程(苹果CMS批量添加视频,快速提升网站内容质量) vue怎么使用npm停止(从 jQuery 到 Vue3 的快捷通道)