toast 全局提示
轻量的全局提示。命令式调用,不需要在模板里放任何东西。
基础用法
<script setup>
import { toast } from '@starriver/ui'
toast.success('操作成功')
toast.info('这是一条普通提示')
toast.warning('请注意这项内容')
toast.error('操作失败了')
</script>Nuxt 里是自动导入的
Nuxt 项目由 layer 自动注册,直接用 toast.success() 即可。 纯 Vue 项目必须显式引入:import { toast } from '@starriver/ui'。
这一点在 vue-playground 里专门验证过——它是最容易在迁移时踩到的差异。
为什么是命令式
toast 最常见的用法是在异步回调里报结果:
async function save() {
try {
await api.save(data)
toast.success('保存成功') // ← 直接调用,不需要维护状态
} catch (e) {
toast.error(e.message)
}
}若做成声明式组件(<SrToast v-model="visible" />), 每次提示都要:在组件里加一个 ref、在模板里加一个标签、 在回调里改那个 ref ——三处分散,而且多个提示要多个 ref。
定时与手动关闭
返回值是提示 id,可用于手动关闭。默认 3 秒后自动消失。
const id = toast.info('5 秒后消失', 5000) // 第二个参数是时长(毫秒)
toast.close(id) // 手动关闭
toast.closeAll() // 关闭全部duration 传 0 表示不自动消失,需要用户手动关闭。
什么时候该用 duration: 0
自动消失的提示假设用户一定看到了。但对错误信息来说这个假设不成立—— 用户可能当时在看别处。
需要用户注意到的信息(错误详情、需要复制的内容)应该:
- 用
duration: 0,让用户自己关;或者 - 改用
notification,它有标题、能承载更多内容,位置也更醒目。
普通的成功提示用默认 3 秒即可——它只是确认"操作生效了", 不需要用户记住什么。
没有 key 机制,提示会累积
toast 不支持 key——每次调用都是一条独立提示,多条同时存在时会依次堆叠。
// 三次调用 = 三条提示,全部挂在屏幕上
toast.info('正在保存…', 0)
toast.info('正在保存…', 0)
toast.info('正在保存…', 0)何时该换用 message
会被反复触发的提示不适合用 toast。典型场景是表单校验失败、 批量操作逐条报结果——一秒内可能触发十几次,屏幕会被盖满。
这时改用 message:它支持 key,同 key 的提示会互相覆盖, 并额外提供 loading 类型,适合「正在保存 → 保存成功」这种原地替换。
一句话:单次提示用 toast,会重复的用 message。
:::
useToast 组合式用法
useToast() 返回一组绑定好的方法,并带一个 mounted 状态。
mounted 当前值:false (SSR 阶段为 false,客户端挂载后为 true)
<script setup>
import { useToast } from '@starriver/ui'
const { success, error, mounted } = useToast()
</script>
<template>
<SrButton @click="success('操作成功')">成功</SrButton>
</template>mounted 用于判断能否安全调用——SSR 阶段为 false。 在 onMounted 之外(比如 <script setup> 顶层)调用提示前, 可以用它判断:
const { success, mounted } = useToast()
if (mounted.value) {
success('只在客户端提示')
}实际上 toast.xxx() 在 SSR 下调用不会报错(直接返回 0), 但 mounted 让这个判断更显式。
API
| 方法 | 参数 | 返回 |
|---|---|---|
toast.success(message, duration?) | 文本、时长(默认 3000) | id |
toast.error(message, duration?) | 同上 | id |
toast.warning(message, duration?) | 同上 | id |
toast.info(message, duration?) | 同上 | id |
toast.close(id) | 提示 id | — |
toast.closeAll() | — | — |
useToast() 返回 { success, error, warning, info, close, closeAll, mounted }。
无障碍
- 提示容器带
role="status"与aria-live="polite",读屏软件会朗读出来 - 错误提示用
aria-live="assertive"(组件内部已按类型区分)—— 它需要打断用户当前正在听的内容,因为可能影响后续操作 - 不要自动消失得太快:读屏用户朗读一条 20 字的提示约需 4–5 秒, 默认 3 秒对他们来说不够(这是 WCAG 2.2.1 的要求)
- 提示是纯通知,不应承载唯一的操作入口—— 自动消失意味着用户可能来不及点击