在 UniApp 里封装一个全局 Toast,我学到了什么
提示本文发布于 4 个月前,其中信息可能已经时过境迁...
Toast 提示看起来是一个很小的需求,但在 UniApp 里,要在路由守卫、请求封装这些非组件上下文里统一唤起提示,并没有那么直接。
wot-design-uni 的 Toast 需要在模板中手动放一个 <wd-toast /> 标签,这在组件里用没问题,但如果你在纯 TypeScript 文件里想弹一个提示,就不太行了。
解决问题的思路
核心思路是用 h 函数(Vue 的渲染函数)动态创建 Toast,而不是依赖模板。
typescript
class ToastRenderer {
private container: HTMLElement | null = null;
private vnode: VNode | null = null;
private toastState = ref<ToastOptions>({ show: false });
constructor() {
this.init();
}
private init() {
this.container = document.createElement("div");
this.container.id = "toast-container";
document.body.appendChild(this.container);
watch(
() => this.toastState.value,
() => this.renderToast(),
{ deep: true, immediate: true }
);
}
// ... 渲染逻辑
}然后通过一个全局实例暴露出去:
typescript
export const toast = new GlobalToast();
// 在任何地方都能用
toast.success("操作成功!");
toast.error("操作失败,请重试");
toast.loading("加载中...");几个关键细节
- 状态管理:用
ref包裹状态,通过watch驱动重新渲染 - 自动销毁:设置
duration定时器,超时自动hide() - 遮罩层:需要覆盖背景点击时,通过
cover参数控制 - 图标处理:用内联 SVG 模拟 wot-design-uni 的图标风格,避免引入额外资源
这个封装让我更理解 Vue 的渲染机制
以前用 Vue 写组件,都是模板思维——放个标签、传个属性、等它渲染。但这次用 h 函数 + render 手动控制渲染,让我对 Vue 的渲染机制有了更深的理解。
其实 Vue 的模板最终也是编译成 h 函数的,只是框架帮我们做了这层转换。手动控制渲染的时候,你能更清楚地知道"什么时候该渲染、什么时候该销毁"。
封装一个全局 Toast 这件事看起来小,但它涉及了 Vue 渲染机制、状态管理、组件设计等多个方面的知识。把一个"小东西"做好,有时候比做一个大功能更能检验水平。
