全局通知队列需用Teleport动态挂载到body内专用容器,以避免样式干扰;推荐在index.html中手动添加语义化容器,每个通知实例用v-if控制渲染并配合transition动画,队列通过响应式数组管理生命周期,实现自动销毁与手动关闭。
通知组件通常由业务逻辑(如 API 响应、表单提交成功)触发,不绑定在某个固定页面组件内。如果直接在触发组件内部渲染通知,会受限于父级 overflow、z-index 或 transform 样式,导致通知被裁剪、错位或遮挡。Teleport 的核心价值,就是让通知 DOM 脱离当前组件树,统一挂载到 body 或专用容器中,确保视觉层级和定位不受干扰。
推荐在 index.html 的 <body> 底部手动添加一个语义化容器,比如:
<div id="notification-container"></div>
这样做的好处是:避免 Teleport 多次创建同名目标时的冲突;便于集中管理样式和 z-index;支持 SSR 和服务端预渲染;也方便后续做动画队列控制或无障碍属性注入。
每个通知实例(如 Toast)都应包裹在 <Teleport to="#notification-container"> 内。关键点在于:
visible、message、type)v-if 控制是否渲染,而不是 v-show —— 避免隐藏但保留在 DOM 中影响队列逻辑<transition> 实现入场/退场动画,且动画只作用于 Teleport 内部元素示例片段:
<Teleport to="#notification-container">
<transition name="notify-fade">
<div v-if="show" class="notify-item">{{ message }}</div>
</transition>
</Teleport>
全局队列本质是一个响应式数组(如 ref([])),每调用一次 notify() 就 push 一个带唯一 ID 和定时器的任务。Teleport 不参与队列管理,但它让每个通知能独立渲染、独立销毁:
id(如 Date.now() + Math.random())setTimeout,时间到则从队列中 splice 掉对应项v-if 重判 → 对应 Teleport 内容自动卸载close(id))这样,Teleport 只负责“投递位置”,队列逻辑负责“生命周期”,二者解耦清晰,扩展性强。