一行代码全局弹出,跨层级通信的秘密武器竟然是它?
🍞 开头:我想弹个通知,结果被 UI 库“绑架”了
react-vant 的 Toast 很好用,但只能显示“文字”或“加载中”。
可我想显示:
👤 3 条新消息
🔔 6 个提醒
✉ 9 封邮件
UI 库说:“不支持,自己写。”
我翻遍文档,发现要么用 Context(太重),要么层层传 props(太蠢)。
直到我遇见了 mitt ——一个只有 200 行代码的“事件总线”,轻得像一张纸。
🚌 mitt 是什么?一个“公交车站”
想象 mitt 是一个公交车站:
- 任何组件都可以上车(emit 事件)
- 任何组件也可以等车(on 监听事件)
比如,我在 ToastController.js 里设了个站:
// ToastController.js
import mitt from 'mitt';
export const toastEvents = mitt();
export function showToast(user = 0, bell = 0, mail = 0) {
toastEvents.emit('show', { user, bell, mail }); // 发车!
}
然后,Toast 组件在车站等车:
// Toast.jsx
useEffect(() => {
const show = (info) => {
setData(info);
setVisible(true);
setTimeout(() => setVisible(false), 3000);
};
toastEvents.on('show', show); // 上车!
return () => toastEvents.off('show', show); // 下车!
}, []);
🎯 使用起来有多爽?
在任意组件,比如 Home.jsx:
import { showToast } from '@/components/Toast/ToastController';
<Button onClick={() => showToast(3, 6, 9)}>
弹个通知!
</Button>
不需要 import Toast 组件,不需要传 props,不需要 context——
只要调用 showToast,通知就“从天而降”。
🎨 样式细节:让它看起来像“官方出品”
position: fixed+bottom: 120px(避开 TabBar)animation: fadeIn(淡入动画)- 三角形箭头(用 border hack 实现)
- z-index: 1000(确保不被遮挡)
.toastArrow {
position: absolute;
bottom: -12px;
right: 32px;
width: 0;
height: 0;
border-left: 12px solid transparent;
border-right: 12px solid transparent;
border-top: 12px solid #1890ff;
}
面试官问:“跨组件通信你怎么做的?”
我:“mitt 事件总线,轻量、解耦、一行调用。”
🎯 结尾:小工具,大智慧
这个 Toast 虽小,却体现了前端工程的核心思想:
- 解耦:调用方和实现方完全无关
- 复用:全站任意地方可用
- 可控:自动消失、动画、样式统一
有时候,最好的架构,不是最复杂的,而是最合适的。
🧭 最终章:我的 TripApp,不止是一个项目
从空文件夹,到像素级还原设计稿;
从 TabBar 高亮,到瀑布流滚动;
从防抖搜索,到 AI 聊天;
从自定义 Toast,到工程化规范……
我的 TripApp 或许永远不会上线 App Store,但它承载了我对前端的热爱、思考与坚持。
每一个组件,都是旅途中的一块路标;每一行代码,都是写给未来的自己的一封信。
感谢你陪我走完这段 React Trip 之旅。
愿你的代码,也如旅途般精彩 🧳✨