#Notification 通知
基于 Radix Vue 的 Toast 组件构建,提供灵活的通知提示功能。 支持多种变体、位置配置、自动关闭、滑动关闭等特性。
基于 BrConfigProvider 实现全局主题配置,支持组件式/函数式两种调用方式。
#组件特性
- 🎨 6 种视觉变体:支持
default、primary、success、warning、error、info。 - 📐 4 种位置:支持
top-right、top-left、bottom-right、bottom-left。 - ⏱️ 自动关闭:支持
duration属性控制自动关闭时间。 - ❌ 可关闭:支持滑动手势关闭和关闭按钮。
- 🎬 操作按钮:支持自定义操作按钮。
- 🖼️ 图标支持:每种变体类型都有内置图标。
- 🎨 主题定制:基于
BrConfigProvider支持全局主题配置和 TailwindCSS 局部覆盖。
#基础用法
最简单的通知提示。
<template>
<div>
<BrNotificationProvider group="basic" />
<BrButton @click="showNotification">Show Notification</BrButton>
</div>
</template>
<script setup lang="ts">
import { useNotification, BrButton, BrNotificationProvider } from '@breezeui/vue'
const { toast } = useNotification()
function showNotification() {
toast({
group: 'basic',
title: 'Schedule Reminder',
description: 'You have a meeting starting in 15 minutes。',
})
}
</script>#变体样式
支持 default, primary, success, error, warning, info 六种变体。
<template>
<div class="flex gap-4 flex-wrap">
<BrNotificationProvider group="variants" />
<BrButton variant="outline" @click="show('default')">Default</BrButton>
<BrButton color="primary" @click="show('primary')">Primary</BrButton>
<BrButton color="success" @click="show('success')">Success</BrButton>
<BrButton color="danger" @click="show('error')">Error</BrButton>
<BrButton color="warning" @click="show('warning')">Warning</BrButton>
<BrButton color="info" @click="show('info')">Info</BrButton>
</div>
</template>
<script setup lang="ts">
import { useNotification, BrButton, BrNotificationProvider } from '@breezeui/vue'
import type { NotificationVariant } from '@breezeui/vue'
const { toast } = useNotification()
function show(variant: NotificationVariant) {
toast({
group: 'variants',
title: variant.charAt(0).toUpperCase() + variant.slice(1) + ' Notification',
description: 'This is a ' + variant + ' notification.',
variant,
})
}
</script>#位置与持续时间
支持通过 BrNotificationProvider 配置弹出的位置(top-left/top-right/bottom-left/bottom-right)以及自动关闭的时间。
<script setup lang="ts">
import { ref } from 'vue'
import { BrButton, BrNotificationProvider, useNotification } from '@breezeui/vue'
import type { NotificationPosition } from '@breezeui/vue'
const { toast, dismiss } = useNotification()
const position = ref<NotificationPosition>('top-left')
const duration = ref(2800)
const positionOptions: { label: string; value: NotificationPosition }[] = [
{ label: 'top-left', value: 'top-left' },
{ label: 'top-right', value: 'top-right' },
{ label: 'bottom-left', value: 'bottom-left' },
{ label: 'bottom-right', value: 'bottom-right' },
]
function notify() {
toast({
group: 'positions',
title: 'Custom Position',
description: `position=${position.value} duration=${duration.value}ms`,
duration: duration.value,
})
}
function spam() {
for (let i = 1; i <= 4; i += 1) {
toast({
group: 'positions',
title: `Notification ${i}`,
description: 'Stacked display',
duration: duration.value + i * 250,
variant: i % 2 === 0 ? 'primary' : 'default',
})
}
}
</script>
<template>
<div class="space-y-6">
<BrNotificationProvider group="positions" :position="position" :duration="duration" />
<!-- 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 Notification</BrButton>
<BrButton variant="outline" @click="spam">Stack Notifications</BrButton>
<BrButton variant="outline" @click="dismiss()">Dismiss All</BrButton>
</div>
</div>
</div>
</template>#带操作按钮
可以添加操作按钮来处理用户交互。
<template>
<div>
<BrNotificationProvider group="action" />
<BrButton @click="showAction">With Action Button</BrButton>
</div>
</template>
<script setup lang="ts">
import { useNotification, BrButton, BrNotificationProvider } from '@breezeui/vue'
const { toast } = useNotification()
function showAction() {
toast({
group: 'action',
title: 'Update Available',
description: 'New version v1.2.0 has been released。',
action: {
label: 'Update Now',
onClick: () => console.log('Update clicked'),
},
})
}
</script>#API
#BrNotification
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| title | string | - | 通知的标题 |
| description | string | - | 通知的描述内容 |
| variant | 'default' | 'primary' | 'success' | 'error' | 'warning' | 'info' | 'default' | 通知的变体样式 |
| duration | number | 5000 | 自动关闭的延迟时间(毫秒) |
| dismissible | boolean | true | 是否显示关闭按钮 |
| action | NotificationAction | - | 操作按钮配置 |
| icon | Component | - | 自定义图标组件 |
#BrNotificationProvider
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| position | 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right' | 'bottom-right' | 通知显示的位置 |
| duration | number | 5000 | 默认自动关闭时间 |
| swipeDirection | 'up' | 'down' | 'left' | 'right' | 'right' | 滑动关闭的方向 |
| swipeThreshold | number | 50 | 滑动关闭的阈值 |
#useNotification
| 方法 | 参数 | 返回值 | 说明 |
|---|---|---|---|
| toast | props: Omit<NotificationProps, 'id'> | { id, dismiss, update } | 创建并显示一条通知 |
| dismiss | id?: string | - | 关闭指定 id 的通知,若不传则关闭所有 |
| toasts | - | Ref<NotificationProps[]> | 当前所有通知的响应式列表 |
#主题定制
#全局配置 (BrConfigProvider)
通过 BrConfigProvider 可以全局配置 Notification 的样式变量。
<template>
<BrConfigProvider :theme="themeConfig">
<BrNotificationProvider>
<App />
</BrNotificationProvider>
</BrConfigProvider>
</template>
#TailwindCSS 覆盖
可以通过 class 属性直接覆盖样式。
toast({
title: 'Custom Style',
class: 'bg-purple-500 text-white border-none',
})