Mitt 事件发射器完全指南:200字节的轻量级解决方案

简介

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 是一个简单而强大的事件发射器,通过合理使用可以大大简化组件间通信和状态管理。掌握这些用法和最佳实践,将帮助您构建更加健壮和可维护的应用程序。

Mitt 事件发射器完全指南:200字节的轻量级解决方案 - 高质量源码分享平台-免费下载各类网站源码与模板及前沿技术分享

相关推荐
ruanno_top3 小时前
选中一项后,焦点掉回了页面顶部:三个弹层的焦点还原
vue.js
tryCbest5 小时前
Vue3——第 17 篇:模板引用(ref)与组件实例——操作 DOM 的正确姿势
vue.js·前端搭建
头发还在的女程序员6 小时前
Java在线租房系统源码解析:Spring Boot+Vue 3+UniApp房源管理与预约看房方案
java·vue.js·spring boot·租房小程序·租房系统·租房软件
FYKJ_20106 小时前
springboot同人周边订单管理系统48955-计算机毕业设计、课程设计
java·javascript·vue.js·spring boot·django·php·课程设计
梯度下降者16 小时前
Nuxt框架
vue.js·服务端渲染·全栈开发·混合渲染·nuxt框架
生活的囚徒20 小时前
从一堆Excel到一套系统:项目管理+研发管理双门户的落地实践
react.js
yuyuxun11 天前
协同过滤的校园二手物品智能推荐系统的设计与实现 毕业设计-附源码40082
javascript·vue.js·spring boot·python·数据分析·django·课程设计
FungLeo1 天前
成为全栈·Vue 管理后台篇·编辑器图片上传:从文件选择到文章附件关联
前端·vue.js·编辑器·markdown·文件上传·formdata·附件管理
码云社区1 天前
智慧物业系统选型指南:房屋档案、账单管理与报修协作
前端·javascript·vue.js·智慧物业
ruanno_top2 天前
表单重置后,验证码还显示已通过:Vue 受控组件的 3 种假同步
vue.js