vue-pure-admin消息通知系统:实时消息推送与状态管理

【免费下载链接】vue-pure-admin 全面ESM+Vue3+Vite+Element-Plus+TypeScript编写的一款后台管理系统(兼容移动端) 【免费下载链接】vue-pure-admin 项目地址: https://gitcode.com/GitHub_Trending/vu/vue-pure-admin

概述

在现代Web应用中,实时消息通知系统是提升用户体验的关键功能。vue-pure-admin基于Vue3+TypeScript+Pinia技术栈,构建了一套完整的消息通知解决方案,支持多种消息类型、实时状态管理和优雅的用户交互体验。

系统架构设计

核心组件结构

mermaid

消息数据类型定义

系统支持三种主要消息类型:

消息类型 标识符 描述 典型应用场景
通知消息 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';
}

故障排除与调试

常见问题解决方案

问题现象 可能原因 解决方案

【免费下载链接】vue-pure-admin 全面ESM+Vue3+Vite+Element-Plus+TypeScript编写的一款后台管理系统(兼容移动端) 【免费下载链接】vue-pure-admin 项目地址: https://gitcode.com/GitHub_Trending/vu/vue-pure-admin

更多推荐