简介
Mitt 是一个轻量级的事件发射器库,体积小巧(约 200 字节),无依赖,支持 TypeScript。它提供了简单而强大的事件发布/订阅机制,适用于组件间通信、状态管理等场景。
特点
- 🚀 超轻量级(~200 bytes)
- 🔧 无依赖
- 📝 TypeScript 支持
- 🎯 简单易用的 API
- 🛡️ 类型安全
安装
npm install mitt
基本用法
创建事件发射器
import mitt from "mitt";
// 创建事件发射器实例
const emitter = mitt();
// 或者指定事件类型
type Events = {
foo: string;
bar: number;
baz: void;
};
const typedEmitter = mitt<Events>();
监听事件
// 监听单个事件
emitter.on("foo", (data) => {
console.log("收到 foo 事件:", data);
});
// 监听多个事件
emitter.on("bar", (data) => {
console.log("收到 bar 事件:", data);
});
// 使用通配符监听所有事件
emitter.on("*", (type, data) => {
console.log(`事件类型: ${type}, 数据:`, data);
});
发射事件
// 发射事件(无数据)
emitter.emit("baz");
// 发射事件(带数据)
emitter.emit("foo", "hello world");
emitter.emit("bar", 42);
移除监听器
// 移除特定事件的监听器
emitter.off("foo");
// 移除所有监听器
emitter.all.clear();
// 移除特定监听器(需要保存引用)
const handler = (data: string) => console.log(data);
emitter.on("foo", handler);
emitter.off("foo", handler);
API 详解
mitt()
创建一个新的事件发射器实例。
const emitter = mitt<Events>();
emitter.on(type, handler)
注册事件监听器。
参数:
type
: 事件类型(字符串或通配符 ‘*’)handler
: 事件处理函数
返回值: 无
emitter.on("message", (data: string) => {
console.log("收到消息:", data);
});
emitter.off(type, handler?)
移除事件监听器。
参数:
type
: 事件类型handler
: 可选的特定处理函数
返回值: 无
// 移除所有 'message' 事件的监听器
emitter.off("message");
// 移除特定的监听器
const handler = (data: string) => console.log(data);
emitter.off("message", handler);
emitter.emit(type, data?)
发射事件。
参数:
type
: 事件类型data
: 可选的事件数据
返回值: 无
emitter.emit("message", "Hello World");
emitter.emit("notification");
emitter.all
获取所有注册的事件监听器。
// 查看所有事件类型
console.log(Object.keys(emitter.all));
// 清空所有监听器
emitter.all.clear();
高级特性
通配符监听
// 监听所有事件
emitter.on("*", (type, data) => {
console.log(`事件 ${type} 被触发:`, data);
});
// 通配符监听器会收到事件类型作为第一个参数
emitter.emit("foo", "bar");
// 输出: 事件 foo 被触发: bar
链式调用
// 支持链式调用
emitter
.on("event1", () => console.log("event1"))
.on("event2", () => console.log("event2"))
.emit("event1");
常见用例
React 组件间通信
// 创建全局事件发射器
export const globalEmitter = mitt<{
themeChange: "light" | "dark";
userUpdate: { id: string; name: string };
}>();
// 在组件中使用
function ThemeToggle() {
const toggleTheme = () => {
globalEmitter.emit("themeChange", "dark");
};
return <button onClick={toggleTheme}>切换主题</button>;
}
function UserProfile() {
useEffect(() => {
const handler = (user: { id: string; name: string }) => {
console.log("用户信息更新:", user);
};
globalEmitter.on("userUpdate", handler);
return () => globalEmitter.off("userUpdate", handler);
}, []);
return <div>用户资料</div>;
}
Vue 3 组合式 API
// composables/useEventBus.ts
import mitt from "mitt";
import { onUnmounted } from "vue";
export const eventBus = mitt();
export function useEventBus() {
const handlers: Array<() => void> = [];
const on = (event: string, handler: Function) => {
eventBus.on(event, handler);
handlers.push(() => eventBus.off(event, handler));
};
const emit = (event: string, data?: any) => {
eventBus.emit(event, data);
};
onUnmounted(() => {
handlers.forEach((cleanup) => cleanup());
});
return { on, emit };
}
// 在组件中使用
export default {
setup() {
const { on, emit } = useEventBus();
on("message", (data: string) => {
console.log("收到消息:", data);
});
const sendMessage = () => {
emit("message", "Hello from component");
};
return { sendMessage };
},
};
注意事项
内存泄漏
- 始终在组件卸载时清理事件监听器
- 使用
emitter.all.clear()
清空所有监听器 - 保存处理函数引用以便精确移除
事件循环
- 避免在事件处理函数中发射相同事件
- 使用防抖或节流处理高频事件
- 考虑使用
setTimeout
或setImmediate
延迟事件发射
调试技巧
// 开发环境下的调试辅助
if (process.env.NODE_ENV === "development") {
const originalEmit = emitter.emit;
emitter.emit = (type, data) => {
console.log(`[Event] ${type}:`, data);
originalEmit.call(emitter, type, data);
};
}
Mitt 是一个简单而强大的事件发射器,通过合理使用可以大大简化组件间通信和状态管理。掌握这些用法和最佳实践,将帮助您构建更加健壮和可维护的应用程序。
原文链接:https://code.ifrontend.net/archives/1035,转载请注明出处。
评论0