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

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

事件总线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;
  }
};

 

 

专注于代码生成工具、.Net/.NetCore 框架架构及软件开发,以及各种Vue.js的前端技术应用。著有Winform开发框架/混合式开发框架、微信开发框架、Bootstrap开发框架、ABP开发框架、SqlSugar开发框架等框架产品。
 转载请注明出处:撰写人:伍华聪  http://www.iqidi.com

目录
打赏
0
1
1
0
60
分享
相关文章
前端大模型应用笔记(三):Vue3+Antdv+transformers+本地模型实现浏览器端侧增强搜索
本文介绍了一个纯前端实现的增强列表搜索应用,通过使用Transformer模型,实现了更智能的搜索功能,如使用“番茄”可以搜索到“西红柿”。项目基于Vue3和Ant Design Vue,使用了Xenova的bge-base-zh-v1.5模型。文章详细介绍了从环境搭建、数据准备到具体实现的全过程,并展示了实际效果和待改进点。
414 14
Gzm Design:开源神器!用 Vue3、Vite4、TypeScript 革新海报设计,免费开源的海报设计器,主流技术打造,轻松高效
海报设计在各个领域都有着广泛的应用,无论是商业广告、活动宣传还是个人创意表达。今天要给大家介绍一款免费开源的海报设计器——Gzm Design,它基于最新的主流技术开发,为用户提供了丰富的功能,让海报设计变得轻松又高效。
147 64
Vue Amazing UI 组件库(Vue3+TypeScript+Vite 等最新技术栈开发)
Vue Amazing UI 是一个基于 Vue 3、TypeScript、Vite 等最新技术栈开发构建的现代化组件库,包含丰富的 UI 组件和常用工具函数,并且持续不断维护更新中。另外,组件库全量使用 TypeScript,支持自动按需引入和 Tree Shaking 等,能够显著提升开发效率,降低开发成本。
86 5
Vue Amazing UI 组件库(Vue3+TypeScript+Vite 等最新技术栈开发)
前端项目代码规范工具 (ESLint. Prettier. Stylelint. TypeScript)
前端项目代码规范工具 (ESLint. Prettier. Stylelint. TypeScript)
242 4
2024年前端开发新趋势:TypeScript、Deno与性能优化
2024年前端开发迎来新趋势:TypeScript 5.0引入装饰器正式支持、const类型参数及枚举改进;Deno 1.42版推出JSR包注册表、增强Node.js兼容性并优化性能;性能优化策略涵盖代码分割、懒加载及现代构建工具的应用。这些变化推动前端开发向更高效率和安全性发展。
vite3+vue3 实现前端部署加密混淆 javascript-obfuscator
【11月更文挑战第10天】本文介绍了在 Vite 3 + Vue 3 项目中使用 `javascript-obfuscator` 实现前端代码加密混淆的详细步骤,包括安装依赖、创建混淆脚本、修改 `package.json` 脚本命令、构建项目并执行混淆,以及在 HTML 文件中引用混淆后的文件。通过这些步骤,可以有效提高代码的安全性。
389 2
前端的混合之路Meteor篇(六):发布订阅示例代码及如何将Meteor的响应数据映射到vue3的reactive系统
本文介绍了 Meteor 3.0 中的发布-订阅模型,详细讲解了如何在服务器端通过 `Meteor.publish` 发布数据,包括简单发布和自定义发布。客户端则通过 `Meteor.subscribe` 订阅数据,并使用 MiniMongo 实现实时数据同步。此外,还展示了如何在 Vue 3 中将 MiniMongo 的 `cursor` 转化为响应式数组,实现数据的自动更新。
vite3+vue3 实现前端部署加密混淆 javascript-obfuscator
【11月更文挑战第7天】本文介绍了在 Vite 3 + Vue 3 项目中使用 `javascript-obfuscator` 实现前端代码加密混淆的详细步骤。包括项目准备、安装 `javascript-obfuscator`、配置 Vite 构建以应用混淆,以及最终构建项目进行混淆。通过这些步骤,可以有效提升前端代码的安全性,防止被他人轻易分析和盗用。
895 0
语言不再是壁垒:掌握 JSF 国际化技巧,轻松构建多语言支持的 Web 应用
【8月更文挑战第31天】JavaServer Faces (JSF) 框架提供了强大的国际化 (I18N) 和本地化 (L10N) 支持,使开发者能轻松添加多语言功能。本文通过具体案例展示如何在 JSF 应用中实现多语言支持,包括创建项目、配置语言资源文件 (`messages_xx.properties`)、设置 `web.xml`、编写 Managed Bean (`LanguageBean`) 处理语言选择,以及使用 Facelets 页面 (`index.xhtml`) 显示多语言消息。通过这些步骤,你将学会如何配置 JSF 环境、编写语言资源文件,并实现动态语言切换。
79 1

热门文章

最新文章