vue-pure-admin消息通知系统:实时消息推送与状态管理
·
vue-pure-admin消息通知系统:实时消息推送与状态管理
概述
在现代Web应用中,实时消息通知系统是提升用户体验的关键功能。vue-pure-admin基于Vue3+TypeScript+Pinia技术栈,构建了一套完整的消息通知解决方案,支持多种消息类型、实时状态管理和优雅的用户交互体验。
系统架构设计
核心组件结构
消息数据类型定义
系统支持三种主要消息类型:
| 消息类型 | 标识符 | 描述 | 典型应用场景 |
|---|---|---|---|
| 通知消息 | pureNotify |
系统级通知 | 系统公告、版本更新 |
| 普通消息 | pureMessage |
用户间消息 | 评论、回复、@提及 |
| 待办事项 | pureTodo |
任务提醒 | 任务分配、截止提醒 |
核心实现解析
1. 消息数据结构
export interface ListItem {
avatar: string; // 头像URL
title: string; // 消息标题
datetime: string; // 时间显示
type: string; // 消息类型标识
description: string; // 消息内容
status?: "primary" | "success" | "warning" | "info" | "danger"; // 状态标签
extra?: string; // 额外信息
}
export interface TabItem {
key: string; // 选项卡键值
name: string; // 选项卡名称
list: ListItem[]; // 消息列表
emptyText: string; // 空状态提示文本
}
2. 消息状态管理
系统使用Vue3的组合式API和Pinia进行状态管理:
const noticesNum = ref(0);
const notices = ref(noticesData);
const activeKey = ref(noticesData[0]?.key);
// 计算总消息数量
notices.value.map(v => (noticesNum.value += v.list.length));
// 动态生成选项卡标签(含消息计数)
const getLabel = computed(
() => item =>
t(item.name) + (item.list.length > 0 ? `(${item.list.length})` : "")
);
3. 实时消息推送机制
虽然当前实现基于静态数据,但架构设计支持轻松扩展为实时推送:
// 伪代码:WebSocket消息接收处理
const setupWebSocket = () => {
const ws = new WebSocket('wss://your-websocket-endpoint');
ws.onmessage = (event) => {
const message = JSON.parse(event.data);
// 根据消息类型分发到对应选项卡
const tabIndex = notices.value.findIndex(tab => tab.key === message.type);
if (tabIndex !== -1) {
notices.value[tabIndex].list.unshift(message);
noticesNum.value++;
}
};
// 错误处理和重连逻辑
ws.onerror = (error) => console.error('WebSocket error:', error);
ws.onclose = () => setTimeout(setupWebSocket, 3000);
};
功能特性详解
1. 智能消息计数
系统自动计算各类消息的总数,并在UI上实时显示:
<el-badge :value="Number(noticesNum) === 0 ? '' : noticesNum" :max="99">
<span class="header-notice-icon">
<IconifyIconOffline :icon="BellIcon" />
</span>
</el-badge>
2. 多选项卡消息分类
支持按消息类型分选项卡展示,提升用户体验:
<el-tabs v-model="activeKey" :stretch="true" class="dropdown-tabs">
<template v-for="item in notices" :key="item.key">
<el-tab-pane :label="getLabel(item)" :name="`${item.key}`">
<el-scrollbar max-height="330px">
<NoticeList :list="item.list" :emptyText="item.emptyText" />
</el-scrollbar>
</el-tab-pane>
</template>
</el-tabs>
3. 响应式布局适配
系统自动适配不同屏幕尺寸:
.dropdown-tabs {
:deep(.el-tabs__header) {
margin: 0;
}
:deep(.el-tabs__nav-wrap)::after {
height: 1px;
}
:deep(.el-tabs__nav-wrap) {
padding: 0 36px;
}
}
最佳实践指南
1. 消息数据初始化
export const noticesData: TabItem[] = [
{
key: "1",
name: $t("status.pureNotify"),
list: [],
emptyText: $t("status.pureNoNotify")
},
{
key: "2",
name: $t("status.pureMessage"),
list: [/* 消息数据 */],
emptyText: $t("status.pureNoMessage")
},
// ... 更多消息类型
];
2. 自定义消息项组件
<template>
<div v-if="list.length">
<NoticeItem v-for="(item, index) in list" :key="index" :noticeItem="item" />
</div>
<el-empty v-else :description="transformI18n(emptyText)" />
</template>
3. 状态管理集成
// 在Pinia store中集成消息状态
export const useNotificationStore = defineStore('notification', {
state: () => ({
unreadCount: 0,
messages: [],
lastReceived: null
}),
actions: {
addMessage(message) {
this.messages.unshift(message);
this.unreadCount++;
this.lastReceived = new Date();
},
markAsRead() {
this.unreadCount = 0;
}
}
});
性能优化策略
1. 虚拟滚动支持
对于大量消息场景,启用虚拟滚动:
<el-scrollbar max-height="330px">
<RecycleScroller
:items="filteredMessages"
:item-size="80"
key-field="id"
>
<template #default="{ item }">
<NoticeItem :noticeItem="item" />
</template>
</RecycleScroller>
</el-scrollbar>
2. 消息去重机制
const addMessageWithDeduplication = (newMessage) => {
const exists = notices.value.some(tab =>
tab.list.some(msg => msg.id === newMessage.id)
);
if (!exists) {
// 添加到对应消息类型
const targetTab = notices.value.find(tab => tab.key === newMessage.type);
if (targetTab) {
targetTab.list.unshift(newMessage);
noticesNum.value++;
}
}
};
3. 本地存储优化
// 自动保存已读状态到localStorage
watch(noticesNum, (newVal) => {
if (newVal === 0) {
localStorage.setItem('messagesAllRead', Date.now().toString());
}
});
扩展开发指南
1. 集成第三方消息服务
// 集成Firebase Cloud Messaging
import { getMessaging, onMessage } from "firebase/messaging";
const messaging = getMessaging();
onMessage(messaging, (payload) => {
const notification = payload.notification;
addMessage({
title: notification.title,
description: notification.body,
type: '1', // 通知类型
datetime: new Date().toLocaleDateString()
});
});
2. 消息推送API设计
// RESTful消息推送接口
export const pushNotification = async (message: PushMessage) => {
const response = await fetch('/api/notifications/push', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(message)
});
return response.json();
};
interface PushMessage {
userId: string;
title: string;
content: string;
type: 'info' | 'warning' | 'error' | 'success';
priority: 'low' | 'normal' | 'high';
}
故障排除与调试
常见问题解决方案
| 问题现象 | 可能原因 | 解决方案 |
|---|
更多推荐
所有评论(0)