Appearance
BizNotificationCenter 通知中心
中后台顶栏标配:铃铛 + 未读角标 + 下拉通知列表(级别圆点 / 未读降透明度 / 时间)+ 全部已读 / 查看全部。数据与已读状态由业务侧维护,组件纯展示 + 事件回调。
基础用法
运营后台5 分钟前32 分钟前2 小时前昨天
3
通知(3 条未读)
审批待办
采购单 CG-2088 等待您审批(金额 ¥86,400)
库存告警
SKU-9981 库存低于安全水位(剩 12 件)
系统公告
平台将于 09-26 凌晨停机升级
发货成功
订单 SO-1002 已签收
查看全部
notifications 注入列表(level 分级圆点、read 降透明);全部已读 / 点击单条已读由业务侧回写数据。<script setup lang="ts">
/** 基础用法:铃铛 + 未读角标 + 下拉列表(全部已读 / 查看全部) */
import { ref } from 'vue'
import { ElMessage } from 'element-plus'
import { BizNotificationCenter } from 'vue3-ep-biz-lib'
import type { BizNotificationItem } from 'vue3-ep-biz-lib'
const notifications = ref<BizNotificationItem[]>([
{ id: 1, title: '审批待办', content: '采购单 CG-2088 等待您审批(金额 ¥86,400)', time: '5 分钟前', level: 'warning' },
{ id: 2, title: '库存告警', content: 'SKU-9981 库存低于安全水位(剩 12 件)', time: '32 分钟前', level: 'danger' },
{ id: 3, title: '系统公告', content: '平台将于 09-26 凌晨停机升级', time: '2 小时前', level: 'info' },
{ id: 4, title: '发货成功', content: '订单 SO-1002 已签收', time: '昨天', level: 'success', read: true },
])
const onReadAll = (): void => {
notifications.value = notifications.value.map((item) => ({ ...item, read: true }))
ElMessage.success('已全部标记为已读')
}
const onItemClick = (item: BizNotificationItem): void => {
const index = notifications.value.findIndex((n) => n.id === item.id)
if (index >= 0) notifications.value[index] = { ...item, read: true }
ElMessage.info(`打开通知:${item.title}`)
}
</script>
<template>
<div style="display: flex; align-items: center; gap: 16px; max-width: 560px; padding: 12px 16px; border: 1px solid var(--el-border-color-lighter); border-radius: 6px">
<span style="font-weight: 600">运营后台</span>
<span style="flex: 1" />
<BizNotificationCenter :notifications="notifications" @read-all="onReadAll" @item-click="onItemClick" @view-all="ElMessage.info('前往通知中心')" />
</div>
</template>
显示代码
顶栏空态与推送
通知(0 条未读)
暂无通知
查看全部
空列表内置 BizEmpty 空态;角标未读数为 0 时自动隐藏。
<script setup lang="ts">
/** 场景:顶栏常驻——空态兜底 + 模拟推送 */
import { ref } from 'vue'
import { ElButton, ElMessage } from 'element-plus'
import { BizNotificationCenter } from 'vue3-ep-biz-lib'
import type { BizNotificationItem } from 'vue3-ep-biz-lib'
const list = ref<BizNotificationItem[]>([])
const pushOne = (): void => {
list.value = [{ id: Date.now(), title: '新告警', content: '温度超限 82℃(模拟推送)', time: '刚刚', level: 'danger' }]
}
</script>
<template>
<div style="display: flex; align-items: center; gap: 12px; max-width: 560px; padding: 12px 16px; border: 1px solid var(--el-border-color-lighter); border-radius: 6px">
<BizNotificationCenter :notifications="list" @read-all="ElMessage.info('无未读')" @view-all="ElMessage.info('前往通知中心')" />
<span style="font-size: 13px; color: var(--el-text-color-secondary)">空列表展示内置空态</span>
<ElButton size="small" type="primary" plain @click="pushOne">模拟推送一条</ElButton>
</div>
</template>
显示代码
告警值班铃铛
监控值班台1 分钟前18 分钟前1 小时前
3
通知(3 条未读)
CRITICAL:支付网关超时率 8.2%
连续 5 分钟超阈值,已自动扩容 2 个实例
WARN:库存同步延迟
队列积压 1,204 条,预计 10 分钟消化
INFO:例行巡检完成
128 台设备全部在线,无需处理
查看全部
值班场景:danger/warning/info 分级圆点;单条点击即确认已读,全部已读一键处理。
<script setup lang="ts">
/** 场景:告警铃铛——分级圆点 + 单条已读 + 全部已读 */
import { ref } from 'vue'
import { ElMessage } from 'element-plus'
import { BizNotificationCenter } from 'vue3-ep-biz-lib'
import type { BizNotificationItem } from 'vue3-ep-biz-lib'
const alarms = ref<BizNotificationItem[]>([
{ id: 1, title: 'CRITICAL:支付网关超时率 8.2%', content: '连续 5 分钟超阈值,已自动扩容 2 个实例', time: '1 分钟前', level: 'danger' },
{ id: 2, title: 'WARN:库存同步延迟', content: '队列积压 1,204 条,预计 10 分钟消化', time: '18 分钟前', level: 'warning' },
{ id: 3, title: 'INFO:例行巡检完成', content: '128 台设备全部在线,无需处理', time: '1 小时前', level: 'info' },
])
const onItemClick = (item: BizNotificationItem): void => {
const index = alarms.value.findIndex((a) => a.id === item.id)
if (index >= 0) alarms.value[index] = { ...item, read: true }
ElMessage.info(`处理告警:${item.title}`)
}
const onReadAll = (): void => {
alarms.value = alarms.value.map((a) => ({ ...a, read: true }))
ElMessage.success('告警已全部确认')
}
</script>
<template>
<div style="display: flex; gap: 14px; align-items: center; max-width: 560px; padding: 12px 16px; border: 1px solid var(--el-border-color-lighter); border-radius: 6px">
<span style="font-weight: 600">监控值班台</span>
<span style="flex: 1" />
<BizNotificationCenter :notifications="alarms" :max-height="260" @item-click="onItemClick" @read-all="onReadAll" @view-all="ElMessage.info('前往告警中心')" />
</div>
</template>
显示代码
审批待办铃铛
3
通知(3 条未读)
采购单 CG-2088 待审批
金额 ¥86,400,等待财务复核
出差报销 BX-0771 待确认
李娜提交,合计 ¥3,280
权限申请待处理
王强申请「报表导出」权限
查看全部
OA 场景:下拉项点击即完成该待办(从未读移除并计数),read-all 派发但由业务侧决定是否允许批量。
<script setup lang="ts">
/** 场景:审批待办铃铛——点开即办(item-click 携带完整对象) */
import { ref } from 'vue'
import { ElMessage, ElTag } from 'element-plus'
import { BizNotificationCenter } from 'vue3-ep-biz-lib'
import type { BizNotificationItem } from 'vue3-ep-biz-lib'
const todos = ref<BizNotificationItem[]>([
{ id: 1, title: '采购单 CG-2088 待审批', content: '金额 ¥86,400,等待财务复核', time: '10 分钟前', level: 'warning' },
{ id: 2, title: '出差报销 BX-0771 待确认', content: '李娜提交,合计 ¥3,280', time: '2 小时前', level: 'info' },
{ id: 3, title: '权限申请待处理', content: '王强申请「报表导出」权限', time: '昨天', level: 'info' },
])
const handled = ref(0)
const onItemClick = (item: BizNotificationItem): void => {
todos.value = todos.value.filter((todo) => todo.id !== item.id)
handled.value += 1
ElMessage.success(`已处理:${item.title}`)
}
</script>
<template>
<div style="display: flex; gap: 14px; align-items: center; max-width: 560px; padding: 12px 16px; border: 1px solid var(--el-border-color-lighter); border-radius: 6px">
<BizNotificationCenter :notifications="todos" @item-click="onItemClick" @read-all="ElMessage.info('待办不可批量已读')" @view-all="ElMessage.info('待办中心')">
</BizNotificationCenter>
<ElTag size="small" type="success">本次已办 {{ handled }} 项</ElTag>
<span style="font-size: 13px; color: var(--el-text-color-secondary)">点击下拉项即完成并从未读移除</span>
</div>
</template>
显示代码
多来源合并通知
3
通知(3 条未读)
[系统] 今晚 02:00 停机升级
[审批] 加签等待您处理
采购单 CG-2088 加签财务复核
[告警] 温度超限 82℃
一号车间 3 号工位
[审批] 已通过的申请
出差 BX-0769 已通过
查看全部
工作台场景:系统公告 / 审批待办 / 设备告警同池展示,级别圆点区分来源紧急度。
<script setup lang="ts">
/** 场景:多来源合并——系统/审批/告警同池展示 */
import { ref } from 'vue'
import { ElMessage, ElTag } from 'element-plus'
import { BizNotificationCenter } from 'vue3-ep-biz-lib'
import type { BizNotificationItem } from 'vue3-ep-biz-lib'
const items = ref<BizNotificationItem[]>([
{ id: 1, title: '[系统] 今晚 02:00 停机升级', time: '09:00', level: 'info' },
{ id: 2, title: '[审批] 加签等待您处理', content: '采购单 CG-2088 加签财务复核', time: '10:20', level: 'warning' },
{ id: 3, title: '[告警] 温度超限 82℃', content: '一号车间 3 号工位', time: '11:02', level: 'danger' },
{ id: 4, title: '[审批] 已通过的申请', content: '出差 BX-0769 已通过', time: '昨天', level: 'success', read: true },
])
const counts = { danger: 1, warning: 1, info: 1, success: 0 }
</script>
<template>
<div style="display: flex; gap: 14px; align-items: center; max-width: 600px; padding: 12px 16px; border: 1px solid var(--el-border-color-lighter); border-radius: 6px">
<BizNotificationCenter :notifications="items" @read-all="ElMessage.success('全部已读'); items = items.map((i) => ({ ...i, read: true }))" @item-click="(item: BizNotificationItem) => ElMessage.info(item.title)" @view-all="ElMessage.info('通知中心')" />
<span style="display: flex; gap: 6px">
<ElTag v-for="(count, level) in counts" :key="level" size="small" :type="level === 'danger' ? 'danger' : level === 'warning' ? 'warning' : level === 'success' ? 'success' : 'info'">
{{ level }} {{ count }}
</ElTag>
</span>
</div>
</template>
显示代码
Props
| 属性名 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| notifications | BizNotificationItem[] | [] | 通知列表(业务维护已读态) |
| max-height | number | 320 | 下拉列表最大高度 |
| bell-size | number | 18 | 铃铛图标尺寸 |
| max-badge | number | 99 | 角标上限(超过显示 99+) |
Events
| 事件名 | 参数 | 说明 |
|---|---|---|
| item-click | (item) | 点击单条(业务侧置已读并跳转) |
| read-all | — | 全部已读 |
| view-all | — | 查看全部(跳通知中心页) |
Slots
| 插槽名 | 说明 |
|---|---|
| — | 无自定义插槽 |
Expose
| 属性/方法 | 说明 |
|---|---|
| — | 无暴露实例 |