#Toast 吐司
用于展示短暂且不打断用户操作的反馈信息,支持自动关闭、手动关闭、堆叠展示、进度条提示、ESC 快捷键关闭、响应式视口适配与显示/隐藏动画。
BrToast 基于 BrConfigProvider 实现全局主题配置(颜色/圆角/阴影/z-index 等 tokens),同时支持组件式与函数式两种调用方式。
#组件特性
- ⏱️ 自动关闭:支持自动关闭和手动关闭两种模式。
- 📚 堆叠展示:支持多个 Toast 同时堆叠显示。
- 📊 进度条提示:可选显示关闭进度条,直观了解剩余时间。
- ⌨️ 快捷键关闭:支持 ESC 快捷键关闭。
- 📐 8 个弹出位置:支持 top/top-left/top-center/top-right/bottom/bottom-left/bottom-center/bottom-right。
- 🎨 多种变体:支持 Default、Primary、Success、Error、Warning、Info 等视觉风格。
- 🎨 主题配置:基于
BrConfigProvider实现全局主题配置(颜色/圆角/阴影/z-index 等 tokens)。
#基础用法
点击按钮后弹出默认样式 Toast(自动关闭 + 可手动关闭)。
<script setup>
import { BrButton, BrToastProvider, useToast } from '@breezeui/vue'
const { toast } = useToast()
function notify() {
toast({
group: 'basic',
title: 'Saved',
description: 'Your changes have been saved successfully.',
showProgress: true,
})
}
</script>
<template>
<div class="flex items-center gap-3">
<BrToastProvider group="basic" />
<BrButton @click="notify">Show Toast</BrButton>
</div>
</template>#变体
使用 variant 属性控制 Toast 的视觉风格:
- Default:默认风格
- Primary:主色风格
- Success:成功色风格
- Error:错误色风格
- Warning:警告色风格
- Info:信息色风格
<script setup>
import { BrButton, BrToastProvider, useToast } from '@breezeui/vue'
const { toast } = useToast()
</script>
<template>
<div class="flex flex-wrap items-center gap-3">
<BrToastProvider group="variants" />
<BrButton @click="toast({ group: 'variants', title: 'Default', description: 'default variant' })">Default</BrButton>
<BrButton color="primary" @click="toast({ group: 'variants', title: 'Primary', description: 'primary variant', variant: 'primary' })">Primary</BrButton>
<BrButton color="success" @click="toast({ group: 'variants', title: 'Success', description: 'success variant', variant: 'success' })">Success</BrButton>
<BrButton color="danger" @click="toast({ group: 'variants', title: 'Error', description: 'error variant', variant: 'error' })">Error</BrButton>
<BrButton color="warning" @click="toast({ group: 'variants', title: 'Warning', description: 'warning variant', variant: 'warning' })">Warning</BrButton>
<BrButton color="info" @click="toast({ group: 'variants', title: 'Info', description: 'info variant', variant: 'info' })">Info</BrButton>
</div>
</template>#位置与堆叠
支持 8 个弹出位置(top/top-left/top-center/top-right/bottom/bottom-left/bottom-center/bottom-right),并支持堆叠展示与进度条提示。
<script setup>
import { ref } from 'vue'
import { BrButton, BrToastProvider, useToast } from '@breezeui/vue'
const { toast, dismiss } = useToast()
const position = ref('top-left')
const duration = ref(2800)
const positionOptions = [
{ label: 'top', value: 'top' },
{ label: 'top-left', value: 'top-left' },
{ label: 'top-center', value: 'top-center' },
{ label: 'top-right', value: 'top-right' },
{ label: 'bottom', value: 'bottom' },
{ label: 'bottom-left', value: 'bottom-left' },
{ label: 'bottom-center', value: 'bottom-center' },
{ label: 'bottom-right', value: 'bottom-right' },
]
function notify() {
toast({
group: 'positions',
title: 'Custom Position',
description: `position=${position.value} duration=${duration.value}ms`,
position: position.value,
duration: duration.value,
})
}
function spam() {
for (let i = 1; i <= 4; i += 1) {
toast({
group: 'positions',
title: `Toast ${i}`,
description: 'Stacked display',
position: position.value,
duration: duration.value + i * 250,
variant: i % 2 === 0 ? 'primary' : 'default',
})
}
}
</script>
<template>
<div class="space-y-6">
<BrToastProvider group="positions" :position="position" />
<!-- Position Selection -->
<div class="space-y-3">
<div class="text-sm font-medium text-muted-foreground">Select Position</div>
<div class="flex flex-wrap gap-2">
<BrButton
v-for="opt in positionOptions"
:key="opt.value"
:variant="position === opt.value ? 'solid' : 'outline'"
:color="position === opt.value ? 'primary' : 'default'"
size="sm"
@click="position = opt.value"
>
{{ opt.label }}
</BrButton>
</div>
</div>
<!-- Controls -->
<div class="flex flex-wrap items-end gap-4">
<div class="space-y-1.5">
<label class="text-sm font-medium text-muted-foreground">Duration (ms)</label>
<input
v-model.number="duration"
type="number"
min="500"
step="100"
class="flex h-9 w-32 rounded-md border border-input bg-background px-3 py-1 text-sm shadow-sm transition-colors file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50"
/>
</div>
<div class="flex flex-wrap gap-2">
<BrButton @click="notify">Show Toast</BrButton>
<BrButton variant="outline" @click="spam">Stack Toasts</BrButton>
<BrButton variant="outline" @click="dismiss()">Dismiss All</BrButton>
</div>
</div>
</div>
</template>#主题定制
通过 BrConfigProvider 全局配置 Toast 默认位置、圆角、阴影、各变体颜色、z-index;也可以通过类名局部覆盖样式。
#全局定制(BrConfigProvider)
<script setup>
import { computed } from 'vue'
import { BrButton, BrConfigProvider, BrToastProvider, useToast } from '@breezeui/vue'
const { toast } = useToast()
const theme = computed(() => ({
radius: 0.75,
shadow: '0 20px 25px -5px rgb(0 0 0 / 0.15), 0 8px 10px -6px rgb(0 0 0 / 0.15)',
zToast: 80,
primary: '#6366f1',
success: '#22c55e',
destructive: '#ef4444',
warning: '#f59e0b',
info: '#3b82f6',
}))
const toastConfig = computed(() => ({
position: 'top-right',
duration: 3800,
max: 4,
closeDelay: 220,
}))
</script>
<template>
<BrConfigProvider :theme="theme" :toast="toastConfig">
<div class="space-y-4">
<BrToastProvider group="theme" />
<div class="flex items-center justify-between gap-4 rounded-lg border bg-card p-4">
<div class="space-y-1">
<div class="text-sm font-medium">Theme Preview</div>
<div class="text-sm text-muted-foreground">Configure Toast tokens and default behavior globally via BrConfigProvider</div>
</div>
</div>
<div class="flex flex-wrap gap-3">
<BrButton @click="toast({ group: 'theme', title: 'Primary', description: 'Global configuration', variant: 'primary' })">Primary</BrButton>
<BrButton variant="outline" @click="toast({ group: 'theme', title: 'Success', description: 'success variant', variant: 'success' })">Success</BrButton>
<BrButton variant="outline" @click="toast({ group: 'theme', title: 'Error', description: 'error variant', variant: 'error' })">Error</BrButton>
</div>
</div>
</BrConfigProvider>
</template>#局部定制(TailwindCSS 类名覆盖)
<script setup>
import { BrButton, BrToastProvider, useToast } from '@breezeui/vue'
const { toast } = useToast()
function customStyle() {
toast({
group: 'local',
title: 'Local Override Style',
description: "Only via class override current Toast's appearance",
class: 'rounded-sm shadow-none border-border/60 bg-card text-card-foreground',
showProgress: true,
})
}
</script>
<template>
<div class="flex items-center gap-3">
<BrToastProvider group="local" />
<BrButton variant="outline" @click="customStyle">Local override style</BrButton>
</div>
</template>#API
#BrToast
| Prop | 类型 | 默认值 | 说明 |
|---|---|---|---|
| open | boolean | undefined | 受控打开状态(配合 @update:open/v-model:open 使用)。 |
| defaultOpen | boolean | false | 非受控初始打开状态。 |
| duration | number | undefined | 当前 Toast 自动关闭时间(ms),优先级高于 Provider 的 duration。 |
| variant | 'default' | 'primary' | 'success' | 'error' | 'warning' | 'info' | 'default' | 变体样式。 |
| position | BrToastPosition | undefined | 当前 Toast 的弹出位置(优先级高于 Provider/BrConfigProvider)。 |
| dismissible | boolean | true | 是否显示关闭按钮、允许手动关闭。 |
| showProgress | boolean | false | 是否展示自动关闭进度条(依赖 duration > 0)。 |
| title | string | Component | undefined | 标题内容(不传时可用 #title 插槽)。 |
| description | string | Component | undefined | 描述内容(不传时可用 #description 插槽)。 |
| icon | Component | undefined | 图标内容(不传时可用 #icon 插槽)。 |
| class | string | '' | 追加 TailwindCSS 类名,用于局部覆盖样式。 |
#BrToastProvider
| Prop | 类型 | 默认值 | 说明 |
|---|---|---|---|
| position | BrToastPosition | undefined | 覆盖 BrConfigProvider 的默认位置。 |
| duration | number | undefined | 覆盖 BrConfigProvider 的默认自动关闭时间(ms)。 |
| closeDelay | number | undefined | 关闭后从堆叠列表移除的延迟(ms),用于保留关闭动画。 |
| max | number | undefined | 最大堆叠数量,超出会移除更早的 Toast。 |
| closeOnEscape | boolean | undefined | 是否允许按 ESC 关闭最新 Toast。 |
| viewportClass | string | '' | 追加到视口(Viewport)的类名,用于局部布局覆盖。 |
#useToast
| 字段 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| toast | (options: BrToastOptions) => { id, dismiss, update } | - | 触发 Toast,并返回句柄(可更新/关闭)。 |
| dismiss | (id?: string) => void | - | 关闭指定 Toast;不传 id 关闭全部。 |
| update | (id: string, patch: BrToastOptions) => void | - | 更新指定 Toast 的配置(标题/描述/变体/时长等)。 |
| toasts | Ref<BrToastItem[]> | - | 当前 Toast 列表(用于自定义渲染场景)。 |