经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » JS/JS库/框架 » TypeScript » 查看文章
在Vue3+TypeScript 前端项目中使用事件总线Mitt
来源:cnblogs  作者:伍华聪  时间:2023/3/24 9:11:15  对本文有异议

事件总线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中我们使用的话,不需要类型化事件的类型,如下代码所示。
  1. import mitt from 'mitt'
  2. const emitter = mitt()
  3. // 订阅一个具体的事件
  4. emitter.on('foo', e => console.log('foo', e) )
  5. // 订阅所有事件
  6. emitter.on('*', (type, e) => console.log(type, e) )
  7. // 发布一个事件
  8. emitter.emit('foo', { a: 'b' })
  9. // 根据订阅的函数来取消订阅
  10. function onFoo() {}
  11. emitter.on('foo', onFoo) // listen
  12. emitter.off('foo', onFoo) // unlisten
  13.  
  14. // 只传一个参数,取消订阅同名事件
  15. emitter.off('foo') // unlisten
  16.  
  17. // 取消所有事件
  18. emitter.all.clear()

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

  1. import mitt from "mitt";
  2. type Events = {
  3. foo: string;
  4. bar: number;
  5. };
  6. // 提供泛型参数让 emitter 能自动推断参数类型
  7. const emitter = mitt<Events>();
  8. // 'e' 被推断为string类型
  9. emitter.on("foo", (e) => {
  10. console.log(e);
  11. });
  12. // ts error: 类型 string 的参数不能赋值给类型 'number' 的参数
  13. emitter.emit("bar", "xx");
  14. // ts error: otherEvent 不存在与 Events 的key中
  15. emitter.on("otherEvent", () => {
  16. //
  17. });

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

  1. // utils/mitt.ts
  2. import mitt, { Emitter } from 'mitt';
  3. // 类型
  4. const emitter: Emitter<MittType> = mitt<MittType>();
  5. // 导出
  6. export default emitter;

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

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

  1. declare type MittType<T = any> = {
  2. openSetingsDrawer?: string;
  3. restoreDefault?: string;
  4. setSendColumnsChildren: T;
  5. .................. //省略其他事件类型
  6. noticeRead: number; // 消息已读事件
  7. lastAddParentId?: string | number;//新增记住最后的父信息
  8. };

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

  1. <script lang="ts" setup name="sysMenu">
  2. import { onMounted, onUnmounted, reactive, ref } from 'vue';
  3. import mittBus from '/@/utils/mitt';
  4. ......
  5. onMounted(async () => {
  6. handleQuery();
  7. mittBus.on('submitRefresh', () => {
  8. handleQuery();
  9. });
  10. mittBus.on('lastAddParentId', (pid) => {
  11. state.lastAddParentId = pid as string;//记住最后的父菜单ID
  12. });
  13. });
  14. onUnmounted(() => {
  15. mittBus.off('submitRefresh');
  16. mittBus.off('lastAddParentId');
  17. });
  18. </script>

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

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

  1. // 关闭弹窗
  2. const closeDialog = () => {
  3. mittBus.emit('submitRefresh');
  4. state.isShowDialog = false;
  5. };
  6. // 提交
  7. const submit = () => {
  8. ruleFormRef.value.validate(async (valid: boolean) => {
  9. if (!valid) return;
  10. if (state.ruleForm.id != undefined && state.ruleForm.id > 0) {
  11. await menuApi.update(state.ruleForm);
  12. } else {
  13. await menuApi.add(state.ruleForm);
  14. //记住最后的菜单
  15. mittBus.emit('lastAddParentId', state.ruleForm.pid);
  16. }
  17. closeDialog();
  18. });
  19. };

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

  1. const $u: $u_interface = {
  2. message,
  3. test,
  4. util,
  5. date,
  6. crypto,
  7. base64,
  8. $t: i18n.global.t,
  9. fun: commonFunction(),
  10. cloneDeep,
  11. debounce,
  12. throttle,
  13. mitt
  14. };
  15. //安装$u组件到app上
  16. import type { App } from 'vue';
  17. export default {
  18. install(app: App<Element>) {
  19. // 挂载全局
  20. app.config.globalProperties.$u = $u;
  21. }
  22. };

 

 

 

原文链接:https://www.cnblogs.com/wuhuacong/p/17244470.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号