Mitt 中文文档 | 使用指南

发布时间:2026/7/1 7:05:04
Mitt 中文文档 | 使用指南 版本3.0.1 |大小 200 bytes (gzipped) |协议MITMitt 是一个极致轻量小于200字节的功能性事件发射器/发布-订阅库。它借鉴了 Node.js EventEmitter 的熟悉概念但所有方法都不依赖this非常适合在浏览器或任何 JavaScript 运行时中使用同时支持 IE9。适用场景Mitt 适合跨组件或跨模块的事件通知如A 组件操作后通知 B 组件刷新。如果你需要管理复杂的应用状态请使用 Vuex 或 Pinia。一、安装使用npm或yarn安装npminstallmitt# 或yarnaddmittES Module 方式引入importmittfrommitt;CommonJS 方式引入varmittrequire(mitt);CDN 方式UMDscriptsrchttps://unpkg.com/mitt/dist/mitt.umd.js/script通过 UMD 加载后可以通过 window.mitt 访问。二、用法importmittfrommittconstemittermitt()// 监听一个事件emitter.on(foo,econsole.log(foo,e))// 监听所有事件emitter.on(*,(type,e)console.log(type,e))// 触发一个事件emitter.emit(foo,{a:b})// 清除所有事件emitter.all.clear()// 使用具名函数引用functiononFoo(){}emitter.on(foo,onFoo)// 监听emitter.off(foo,onFoo)// 取消监听三、在 Vue3 中实现兄弟组件通信在 Vue3 中官方移除了$on、$off等方法Mitt 是官方推荐的替代方案。创建事件总线实例src/utils/eventBus.jsimportmittfrommitt;constemittermitt();exportdefaultemitter;发送方组件ComponentA.vuetemplatebutton clicksendMessage发送消息/button/templatescript setupimportemitterfrom/utils/eventBus;functionsendMessage(){emitter.emit(message,来自组件 A 的消息);}/script接收方组件ComponentB.vuetemplatep收到消息{{msg}}/p/templatescript setupimport{ref,onMounted,onUnmounted}fromvue;importemitterfrom/utils/eventBus;constmsgref();functionhandleMessage(data){msg.valuedata;}onMounted((){emitter.on(message,handleMessage);});onUnmounted((){// ⚠️ 关键必须移除监听防止内存泄漏emitter.off(message,handleMessage);});/script父组件App.vuetemplatedivComponentA/ComponentB//div/templatescript setupimportComponentAfrom./components/ComponentA.vue;importComponentBfrom./components/ComponentB.vue;/script四、TypeScript在你的tsconfig.json中设置strict: true可以为 mitt 实例方法获得更好的类型推断。importmittfrommitt;typeEvents{foo:string;bar?:number;};constemittermittEvents();// 被推断为 EmitterEvents 类型emitter.on(foo,(e){});// e 被推断为 string 类型emitter.emit(foo,42);// 错误类型 number 的参数不能赋给类型 string 的参数。(2345)或者你也可以使用提供的Emitter类型importmitt,{Emitter}frommitt;typeEvents{foo:string;bar?:number;};constemitter:EmitterEventsmittEvents();Preact Mitt Codepen Demo五、APImitt创建并返回一个新的Mitt事件发射器实例。示例importmittfrommitt;// 创建一个事件总线实例constemittermitt();// 也可以创建多个独立的实例constuserEmittermitt();constcartEmittermitt();all一个将事件名称映射到已注册处理函数的Map对象。可用于查看所有已注册的事件和监听器。示例constemittermitt();functionhandler1(){}functionhandler2(){}emitter.on(eventA,handler1);emitter.on(eventB,handler2);// 查看所有已注册的事件和监听器console.log(emitter.all);// 输出: Map(2) { eventA [Function: handler1], eventB [Function: handler2] }// 获取所有事件名称console.log([...emitter.all.keys()]);// [eventA, eventB]// 清除所有事件通过 all 属性emitter.all.clear();console.log(emitter.all);// 输出: Map(0) {}on为给定的事件类型注册一个事件处理函数。当该事件被触发时处理函数会被调用。参数type (string | symbol)要监听的事件类型或使用 ‘*’ 监听所有事件handler (Function)在给定事件触发时要调用的函数示例constemittermitt();// 1. 基础用法监听一个事件emitter.on(greet,(name){console.log(你好${name});});// 2. 监听所有事件使用 * 通配符emitter.on(*,(type,data){console.log(事件 ${type} 被触发了数据,data);});// 触发事件查看效果emitter.emit(greet,小明);// 输出: 你好小明// 输出: 事件 greet 被触发了数据 小明off移除给定事件类型的事件处理函数。如果省略 handler将移除该类型的所有处理函数。参数type (string | symbol)要移除处理函数的事件类型或 ‘*’handler (Function, 可选)要移除的处理函数示例constemittermitt();// 定义具名处理函数functiononLogin(data){console.log(用户登录,data);}functiononLogout(data){console.log(用户登出,data);}// 注册监听emitter.on(login,onLogin);emitter.on(login,(data)console.log(登录日志,data));// 匿名函数emitter.on(logout,onLogout);// 1. 移除特定的具名处理函数emitter.off(login,onLogin);emitter.emit(login,{user:admin});// 输出: 登录日志 { user: admin } (onLogin 已被移除不会执行)// 2. 移除某个事件类型的所有处理函数不传 handleremitter.off(login);// 移除 login 的所有监听emitter.emit(login,{user:admin});// 无任何输出因为所有 login 监听都被移除了// 3. 清空所有事件emitter.all.clear();emitter.emit(logout,{user:admin});// 无任何输出emit调用给定类型的所有处理函数。如果存在 ‘*’ 处理函数它们会在类型匹配的处理函数之后被调用。注意不支持手动触发 ‘*’ 处理函数。参数type (string | symbol): 要触发的事件类型。evt (Any, 可选): 传递给处理函数的数据推荐使用对象扩展性更强。注意: 如果存在 ‘*’ 通配符监听器它们会在类型匹配的监听器之后被调用。示例constemittermitt();// 注册多个监听器emitter.on(update,(data){console.log(监听器1 收到更新,data);});emitter.on(update,(data){console.log(监听器2 收到更新,data);});emitter.on(*,(type,data){console.log(通配符监听器事件${type}触发了,data);});// 触发事件传递数据emitter.emit(update,{count:42,timestamp:Date.now()});// 输出顺序:// 监听器1 收到更新 { count: 42, timestamp: 1640000000000 }// 监听器2 收到更新 { count: 42, timestamp: 1640000000000 }// 通配符监听器事件 update 触发了 { count: 42, timestamp: 1640000000000 }// 触发事件不传递数据emitter.emit(refresh);// 输出: 通配符监听器事件 refresh 触发了 undefined六、常见踩坑提醒⚠️ 1. 务必在组件销毁时移除监听这是使用 Mitt 最容易被忽略的问题。如果在onUnmounted中没有移除监听器会导致内存泄漏组件虽然销毁了但监听器仍然存在逻辑混乱多次进入同一页面会反复注册监听导致回调执行多次正确做法onMounted中注册onUnmounted中移除。onMounted((){emitter.on(message,handler);});onUnmounted((){emitter.off(message,handler);});⚠️ 2. 事件命名规范建议统一使用kebab-case短横线连接风格让事件名更规范// ✅ 推荐emitter.emit(item-selected,data);// ❌ 不推荐emitter.emit(itemSelected,data);⚠️ 3. 移除匿名函数无效使用 off 移除监听时必须传入与 on 时相同的函数引用。匿名函数无法被移除// ❌ 错误匿名函数无法被移除emitter.on(foo,(){});emitter.off(foo,(){});// 无效这是两个不同的函数// ✅ 正确使用具名函数functionhandler(){}emitter.on(foo,handler);emitter.off(foo,handler);本文档是对 Mitt 官方文档的中文整理供个人查阅及分享使用。如有错误欢迎指正。————晓说前端 · 一个正在向上爬的技术人如果这篇文章帮到了你可以点个关注一起进阶。