shadcn sonner toast不显示
shadcn sonner toast 因未引入样式而不显示的问题修复记录
#status / growing
#type / debug
#resource / shadcn-vue
[!info] related notes
- 所属 MOC: Shad CN Vue MOC
shadcn sonner toast不显示
现象
在 Vue3 + shadcn/ui 项目中,调用 toast() 函数后页面无任何反应,Toast 通知不弹出。控制台无报错,DOM 中存在 Toaster 组件但不可见。
import { toast } from 'vue-sonner'
function handleClick() {
toast('这是一条通知') // 无任何反应
}
原因
最常见:缺少 vue-sonner 的 CSS 样式导入
shadcn/ui 的 Sonner 组件依赖 vue-sonner 的基础样式。如果没有导入 vue-sonner/style.css,Toast 容器存在但高度为 0、opacity 为 0,视觉上不可见。
其他可能原因
- Toaster 组件未渲染 - 忘记在根组件中添加
<Toaster /> - z-index 冲突 - Toaster 的 z-index 被其他元素覆盖
- CSS 覆盖 - 全局样式覆盖了 sonner 的默认样式
- Provider 顺序 - Toaster 放在了条件渲染组件内部,切换路由后消失
- 暗色模式冲突 - tailwind 的 dark 模式导致 toast 背景色与页面融合
排查步骤
1. 检查 Toaster 组件是否渲染
<!-- App.vue 中必须有 Toaster -->
<template>
<div>
<router-view />
<Toaster /> <!-- 确认存在 -->
</div>
</template>
2. 检查 CSS 是否导入
在使用 Toaster 的组件或全局入口中确认导入:
// 关键:导入 vue-sonner 的基础样式
import 'vue-sonner/style.css'
3. 检查 DOM 中 Toast 容器
打开 DevTools → Elements,搜索 [data-sonner-toaster]:
- 如果不存在:Toaster 组件未正确渲染
- 如果存在但不可见:检查 computed styles(height、opacity、visibility、display)
4. 检查 z-index
/* 在 DevTools 中检查 */
[data-sonner-toaster] {
z-index: 999999; /* sonner 默认值 */
position: fixed;
}
如果页面有 z-index 更高的元素(如模态框),会覆盖 toast。
5. 检查 CSS 全局覆盖
搜索项目中是否有覆盖 sonner 样式的全局 CSS:
/* 可能的问题代码 */
div[data-sonner-toaster] {
display: none; /* 不要这样写 */
}
解决方案
核心修复:导入样式
<script setup lang="ts">
// 关键修复:导入 vue-sonner 样式
import 'vue-sonner/style.css'
import { Toaster } from '@/components/ui/sonner'
</script>
<template>
<div>
<main>
<!-- Your app content -->
</main>
<Toaster />
</div>
</template>
补充:全局导入(推荐)
在 main.ts 中全局导入,避免在每个使用 Toaster 的组件中重复:
// main.ts
import { createApp } from 'vue'
import App from './App.vue'
import 'vue-sonner/style.css' // 全局导入一次
createApp(App).mount('#app')
补充:确保 Toaster 在路由切换后仍存在
<!-- App.vue - Toaster 放在 router-view 外部 -->
<template>
<router-view />
<Toaster position="top-right" :duration="3000" />
</template>
补充:自定义 Toaster 主题
<Toaster
position="top-right"
:toast-options="{
class: 'my-toast',
duration: 3000,
}"
theme="system" // 跟随系统主题
/>
回归验证
- 调用
toast('测试消息')确认 Toast 在页面右上角弹出 - 测试不同类型的 Toast:
toast.success(),toast.error(),toast.info() - 测试 Toast 自动消失(默认 4 秒后关闭)
- 测试手动关闭 Toast(点击关闭按钮)
- 刷新页面后确认 Toast 功能正常(Toaster 组件正确挂载)
- 切换路由后确认 Toast 仍然可用