shadcn sonner toast不显示

shadcn sonner toast 因未引入样式而不显示的问题修复记录

#status / growing #type / debug #resource / shadcn-vue

[!info] related notes

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,视觉上不可见。

其他可能原因

  1. Toaster 组件未渲染 - 忘记在根组件中添加 <Toaster />
  2. z-index 冲突 - Toaster 的 z-index 被其他元素覆盖
  3. CSS 覆盖 - 全局样式覆盖了 sonner 的默认样式
  4. Provider 顺序 - Toaster 放在了条件渲染组件内部,切换路由后消失
  5. 暗色模式冲突 - 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"  // 跟随系统主题
/>

回归验证

  1. 调用 toast('测试消息') 确认 Toast 在页面右上角弹出
  2. 测试不同类型的 Toast:toast.success(), toast.error(), toast.info()
  3. 测试 Toast 自动消失(默认 4 秒后关闭)
  4. 测试手动关闭 Toast(点击关闭按钮)
  5. 刷新页面后确认 Toast 功能正常(Toaster 组件正确挂载)
  6. 切换路由后确认 Toast 仍然可用

相关笔记

创建于 2026/3/5 更新于 2026/5/27