el-badge上角标数据+定时器刷新数据

本文介绍了如何使用Element-UI组件在左上角显示任务进度,通过结合el-badge和定时器实现数据实时刷新。首先展示了静态UI的创建,然后升级到连接接口获取真实数据,并探讨了定时器的性能问题,最后提出使用监听器优化定时器,以减少资源消耗。

背景

在任务图标左上方显示总任务任务进度

需求分析

图标+标记+获取进度接口+实时更新数据

解决方案

使用element-ui的组件

  1. 图标el-icon
    参考文档: https://element.eleme.cn/#/zh-CN/component/icon
  2. 左上角提示el-badge
    参考文档: https://cloud.tencent.com/developer/section/1489890
  3. 获取任务进度并且实时刷新进度==》定时器
    (定时器很消耗性能,暂未学习到其他方法,后续补充)

案例

尝试1:绘制UI,用假数据

效果
效果图

<template>
  <div style=" text-align: center;">
    <h2>进度</h2>
    <!-- el-badge简单用法
     :value="progressData + '%'"显示的数据 
     :hidden="!hasTask" 判断是否要隐藏标记 
     :max="99" 最大值 -->
    <el-badge
      :value="progressData + '%'"
      :max="99"
      :hidden="!hasTask"
      type="warning"
    >
      <i class="el-icon-s-order"></i>
    </el-badge>
  </div>
</template>

<script>
export default {
  data() {
    return {
      //任务列表
      //模拟数据
      taskTable: [
        {
          id: 1,
          taskName: "p1",
          state: "Running",
          progress: 20
        },
        {
          id: 2,
          taskName: "p2",
          state: "End",
          progress: 100
        },
        {
          id: 3,
          taskName: "p3",
          state: "Fail",
          progress: 20
        },
        {
          id: 4,
          taskName: "p4",
          state: "Running",
          progress: 50
        }
      ],
      //正在运行的任务
      countRunningTask: 0,
      //计算出的进度
      progressData: 0
    };
  },
  created() {
    this.getRunningTask();
  },
  methods: {
    //计算进度
    getRunningTask() {
      var tempCountRunningTask = 0;
      var sum = 0;
      for (var i = 0; i < this.taskTable.length; i++) {
        if (this.taskTable[i].state === "Running") {
          sum += this.taskTable[i].progress;
          tempCountRunningTask++;
        }
      }
      this.countRunningTask = tempCountRunningTask;
      this.progressData = Math.ceil(sum / tempCountRunningTask);
    }
  },
  computed: {
    //是否有任务
    hasTask() {
      if (this.countRunningTask == 0) {
        return false;
      }
      return true;
    }
  }
};
</script>

<style></style>

案例二,连上接口,定时刷新数据,获取最新任务进度

尝试2,定时器刷新

控制台添加定时器

  mounted () {
    // 定时刷新任务进度
     this.timer = setInterval(this.getRunningTask, 1000);
  },
  beforeDestroy(){
    // 清楚定时器
     clearTimeout(this.timer);
  },

完整代码:

<template>
  <div style=" text-align: center;">
    <h2>进度</h2>
    <!-- el-badge简单用法
     :value="progressData + '%'"显示的数据 
     :hidden="!hasTask" 判断是否要隐藏标记 
     :max="99" 最大值 -->
    <el-badge
      :value="progressData + '%'"
      :max="99"
      :hidden="!hasTask"
      type="warning"
    >
      <i class="el-icon-s-order"></i>
    </el-badge>
  </div>
</template>

<script>
export default {
  data() {
    return {
      //任务列表
      //模拟数据
      taskTable: [
        // {
        //   id: 1,
        //   taskName: "p1",
        //   state: "Running",
        //   progress: 20
        // },
        // {
        //   id: 2,
        //   taskName: "p2",
        //   state: "End",
        //   progress: 100
        // },
        // {
        //   id: 3,
        //   taskName: "p3",
        //   state: "Fail",
        //   progress: 20
        // },
        // {
        //   id: 4,
        //   taskName: "p4",
        //   state: "Running",
        //   progress: 50
        // }
      ],
      //正在运行的任务
      countRunningTask: 0,
      //计算出的进度
      progressData: 0
    };
  },
  created() {
    this.getRunningTask();
  },
  mounted () {
    // 定时刷新任务进度
     this.timer = setInterval(this.getRunningTask, 1000);
  },
  beforeDestroy(){
    // 清楚定时器
     clearTimeout(this.timer);
  },
  methods: {
    //计算进度
     async  getRunningTask() {
      // 请求接口,利用接口模拟工具
      var api = "http://rap2api.taobao.org/app/mock/300471/getTaskList";
      const { data: res } = await this.$http.get(api);
      this.taskTable=res.data;
      // 开始计算
      var tempCountRunningTask = 0;
      var sum = 0;
      for (var i = 0; i < this.taskTable.length; i++) {
        if (this.taskTable[i].state === "Running") {
          sum += this.taskTable[i].progress;
          tempCountRunningTask++;
        }
      }
      this.countRunningTask = tempCountRunningTask;
      this.progressData = Math.ceil(sum / tempCountRunningTask);
      console.log("当前总进度==》"+this.progressData)
    }
  },
  computed: {
    //是否有任务
    hasTask() {
      if (this.countRunningTask == 0) {
        return false;
      }
      return true;
    }
  }
};
</script>

<style></style>

尝试3,加入监听,优化定时器使用

参考文档:https://blog.youkuaiyun.com/qq_37210523/article/details/103121237

js有两种定时器

setInterval(function(){}, milliseconds)——会不停的调用函数

setTimeout(function(){}, milliseconds)——只执行函数一次

setInterval会符合实时刷新的需求,但是单纯的使用setInterval会导致页面卡死!其原因与JS引擎线程有关, 用通俗话说就是setInterval不会清除定时器队列,每重复执行1次都会导致定时器叠加,最终卡死网页。

优化方案
监听器

 watch: {
    //定时器优化方案
    // progressData是要监听的数据
    progressData: function() {
      const timer = setInterval(() => {
        // 某些定时器操作
        this.getRunningTask();
      }, 500);
      // 通过$once来监听定时器,在beforeDestroy钩子可以被清除。
      this.$once("hook:beforeDestroy", () => {
        clearInterval(timer);
      });
    }
  }

完整

<template>
  <div style=" text-align: center;">
    <h2>进度</h2>
    <!-- el-badge简单用法
     :value="progressData + '%'"显示的数据 
     :hidden="!hasTask" 判断是否要隐藏标记 
     :max="99" 最大值 -->
    <el-badge
      :value="progressData + '%'"
      :max="99"
      :hidden="!hasTask"
      type="warning"
    >
      <i class="el-icon-s-order"></i>
    </el-badge>
  </div>
</template>

<script>
export default {
  data() {
    return {
      //任务列表
      //模拟数据
      taskTable: [
        // {
        //   id: 1,
        //   taskName: "p1",
        //   state: "Running",
        //   progress: 20
        // },
        // {
        //   id: 2,
        //   taskName: "p2",
        //   state: "End",
        //   progress: 100
        // },
        // {
        //   id: 3,
        //   taskName: "p3",
        //   state: "Fail",
        //   progress: 20
        // },
        // {
        //   id: 4,
        //   taskName: "p4",
        //   state: "Running",
        //   progress: 50
        // }
      ],
      //正在运行的任务
      countRunningTask: 0,
      //计算出的进度
      progressData: 0
    };
  },
  created() {
    this.getRunningTask();
  },
  mounted() {
    // 定时刷新任务进度
    // this.timer = setInterval(this.getRunningTask, 1000);
  },
  beforeDestroy() {
    // 清楚定时器
    // clearTimeout(this.timer);
  },
  methods: {
    //计算进度
    async getRunningTask() {
      // 请求接口,利用接口模拟工具
      var api = "http://rap2api.taobao.org/app/mock/300471/getTaskList";
      const { data: res } = await this.$http.get(api);
      this.taskTable = res.data;
      // 开始计算
      var tempCountRunningTask = 0;
      var sum = 0;
      for (var i = 0; i < this.taskTable.length; i++) {
        if (this.taskTable[i].state === "Running") {
          sum += this.taskTable[i].progress;
          tempCountRunningTask++;
        }
      }
      this.countRunningTask = tempCountRunningTask;
      this.progressData = Math.ceil(sum / tempCountRunningTask);
      console.log("当前总进度==》" + this.progressData);
    }
  },
  computed: {
    //是否有任务
    hasTask() {
      if (this.countRunningTask == 0) {
        return false;
      }
      return true;
    }
  },
  watch: {
    //清除定时器优化方案
    progressData: function() {
      const timer = setInterval(() => {
        // 某些定时器操作
        this.getRunningTask();
      }, 500);
      // 通过$once来监听定时器,在beforeDestroy钩子可以被清除。
      this.$once("hook:beforeDestroy", () => {
        clearInterval(timer);
      });
    }
  }
};
</script>

<style></style>

<template> <div> <el-tooltip :content="noticeContent" effect="dark" placement="bottom"> <el-badge :value="noticeCount" class="right-menu-item hover-effect" :class="{ 'badge-custom': noticeCount > 0 }"> <i class="el-icon-message-solid" @click="toNoticePage"></i> </el-badge> </el-tooltip> </div> </template> <script> import { listWbNoticeMessage } from "@/api/websocket/WbNoticeMessage"; export default { name: "InfoBell", props: { refreshNoticeCount: { type: Boolean, default: false } }, data() { return { noticeContent: "", // 通知内容 noticeCount: 0, // 通知数量 socket: null, // WebSocket 实例 // 查询参数 queryParams: { pageNum: 1, pageSize: 10, title: null, content: null, type: null, senderId: null, senderName: null, receiverId: this.$store.state.user.id, receiverName: null, isRead: null, readTime: null, priority: null, targetUrl: null, bizType: null, bizId: null }, }; }, created() { this.getList(); }, mounted() { this.initWebSocket(); }, beforeDestroy() { this.closeWebSocket(); }, watch: { refreshNoticeCount(val) { if (val) { this.getList(); } } }, methods: { /**---------------------websocket专栏-------------------- */ /** 初始化/连接 WebSocket */ initWebSocket() { // const token // 需要鉴权 const currentUserId = this.$store.state.user.id; const currentUserNickName = this.$store.state.user.nickName; const wsUrl = `ws://192.168.3.11:8085/websocket/pushMessage?userId=${currentUserId}&nickName=${currentUserNickName}`; // 替换为你的 WebSocket 地址 this.socket = new WebSocket(wsUrl); this.socket.onopen = () => { console.log("头部导航消息铃铛-WebSocket 连接已建立"); this.startHeartbeat();//启用心跳机制 }; this.socket.onmessage = (event) => { const msg = JSON.parse(event.data); if (msg.type === "pong") { console.log("收到心跳 pong"); return; } this.getList(); }; this.socket.onerror = (error) => { console.error("头部导航消息铃铛-WebSocket 发生错误:", error); }; this.socket.onclose = () => { console.log("头部导航消息铃铛-WebSocket 已关闭"); this.stopHeartbeat(); this.tryReconnect(); }; }, /** 关闭 WebSocket */ closeWebSocket() { if (this.socket) { this.socket.close(); this.socket = null; } this.stopHeartbeat(); if (this.reconnectTimer) { clearInterval(this.reconnectTimer); this.reconnectTimer = null; } }, /** 启动心跳 */ startHeartbeat() { this.heartbeatTimer = setInterval(() => { if (this.socket && this.socket.readyState === WebSocket.OPEN) { this.socket.send(JSON.stringify({ type: "ping" })); console.log("发送心跳 ping"); } }, 30000); // 每 30 秒 }, /** 停止心跳 */ stopHeartbeat() { if (this.heartbeatTimer) { clearInterval(this.heartbeatTimer); this.heartbeatTimer = null; } }, /** 尝试重连 */ tryReconnect() { if (this.reconnectTimer) return; this.reconnectTimer = setInterval(() => { console.log("尝试重连 InfoBell-WebSocket..."); this.initWebSocket(); if (this.socket && this.socket.readyState === WebSocket.OPEN) { clearInterval(this.reconnectTimer); this.reconnectTimer = null; } }, 5000); // 每 5 秒重连一次 }, /** -------------------------- 业务处理专栏---------------------- */ /** 查询通知信息框列表 */ getList() { this.queryParams.isRead = 0; listWbNoticeMessage(this.queryParams).then(response => { this.noticeCount = response.total; this.noticeContent = `您有${this.noticeCount}条未读的信息`; }) }, /** 跳转到通知页面 */ toNoticePage() { this.$router.push("/websocket/pushMessage"); }, }, }; </script> <style lang="scss" scoped> ::v-deep .el-badge__content { margin-top: 9px; margin-right: 1px; } .badge-custom { animation: blink-animation 0.5s infinite alternate; } @keyframes blink-animation { 0% { opacity: 1; } 100% { opacity: 0.1; } } </style>添加script签里的注释
12-03
/** * @file websocket.js * @description WebSocket 工具类 - 支持多连接管理(消息推送+聊天室) * 含完整心跳保活、自动重连、异常处理机制,模块化设计 * @date 2025-12-08 */ // ====================== 全局状态管理(多连接版) ====================== // WebSocket 连接池:key=业务类型,value=连接实例及相关状态 const socketPool = { pushMessage: { // 消息推送业务连接 socket: null, // WebSocket连接实例 heartbeatTimer: null, // 心跳定时器ID reconnectTimer: null, // 重连定时器ID isConnected: false // 当前连接状态 }, chatRoomUserId: { // 聊天室业务连接 socket: null, // WebSocket连接实例 heartbeatTimer: null, // 心跳定时器ID reconnectTimer: null, // 重连定时器ID isConnected: false // 当前连接状态 } }; // 全局消息回调(所有连接共享) let messageCallbacks = []; // 当前登录用户信息,用于重连时重新建立连接 let currentUser = null; // ====================== 核心配置参数 ====================== const WS_CONFIG = { HEARTBEAT_INTERVAL: 30000, // 心跳间隔:30秒(30,000毫秒) RECONNECT_INTERVAL: 5000, // 重连间隔:5秒(5,000毫秒) WS_BASE_URL: 'ws://192.168.3.11:8085/websocket', // WebSocket服务器基础地址 // 业务连接配置映射:业务类型→连接路径 BUSINESS_PATH: { pushMessage: '/pushMessage', // 消息推送业务路径 chatRoomUserId: '/chatRoomUserId' // 聊天室业务路径 } }; // ====================== 私有工具方法(多连接适配) ====================== /** * 获取指定业务类型的连接状态对象 * @param {string} businessType - 业务类型:pushMessage/chatRoom * @returns {Object|null} 连接状态对象,无效业务类型返回null */ const getSocketState = (businessType) => { if (!socketPool[businessType]) { console.error(`[WS] 不支持的业务类型:${businessType}`); return null; } return socketPool[businessType]; }; // ====================== 心跳保活逻辑(多连接版) ====================== /** * 为指定业务类型启用心跳保活机制 * @param {string} businessType - 业务类型:pushMessage/chatRoom * @returns {void} */ const startHeartbeat = (businessType) => { const state = getSocketState(businessType); if (!state) return; // 停止可能存在的旧心跳定时器 stopHeartbeat(businessType); console.log(`[WS-${businessType}] 启动心跳保活(间隔${WS_CONFIG.HEARTBEAT_INTERVAL / 1000}秒)`); // 设置新的心跳定时器 state.heartbeatTimer = setInterval(() => { if (state.isConnected && state.socket) { try { // 发送心跳包,包含业务类型识 state.socket.send(JSON.stringify({ type: 'ping', businessType })); console.log(`[WS-${businessType}] 发送心跳包 → ping`); } catch (e) { console.log(`[WS-${businessType}] 心跳包发送失败:`, e); state.isConnected = false; // 发送失败可能是连接断开 } } }, WS_CONFIG.HEARTBEAT_INTERVAL); }; /** * 停止指定业务类型的心跳保活机制 * @param {string} businessType - 业务类型:pushMessage/chatRoom * @returns {void} */ const stopHeartbeat = (businessType) => { const state = getSocketState(businessType); if (state?.heartbeatTimer) { clearInterval(state.heartbeatTimer); state.heartbeatTimer = null; console.log(`[WS-${businessType}] 停止心跳保活`); } }; // ====================== 自动重连逻辑(多连接版) ====================== /** * 为指定业务类型启动自动重连机制 * @param {string} businessType - 业务类型:pushMessage/chatRoom * @param {string} path - 连接路径 * @param {Object} params - 查询参数 * @param {Function} callback - 连接状态回调函数 * @returns {void} */ const startReconnect = (businessType, path, params, callback) => { const state = getSocketState(businessType); if (!state) return; // 停止可能存在的旧重连定时器 stopReconnect(businessType); console.log(`[WS-${businessType}] 启动自动重连(间隔${WS_CONFIG.RECONNECT_INTERVAL / 1000}秒)`); // 设置新的重连定时器 state.reconnectTimer = setInterval(() => { console.log(`[WS-${businessType}] 尝试重连...`); // 重新初始化WebSocket连接 initWebSocket(businessType, path, params, callback); }, WS_CONFIG.RECONNECT_INTERVAL); }; /** * 停止指定业务类型的自动重连机制 * @param {string} businessType - 业务类型:pushMessage/chatRoom * @returns {void} */ const stopReconnect = (businessType) => { const state = getSocketState(businessType); if (state?.reconnectTimer) { clearInterval(state.reconnectTimer); state.reconnectTimer = null; console.log(`[WS-${businessType}] 停止自动重连`); } }; // ====================== 基础连接初始化(多连接版) ====================== /** * 初始化单个业务的WebSocket连接(核心方法) * @param {string} businessType - 业务类型:pushMessage/chatRoom * @param {string} path - 连接路径 * @param {Object} params - 查询参数对象 * @param {Function} [callback] - 连接状态回调函数 * @returns {void} */ const initWebSocket = (businessType, path, params = {}, callback) => { const state = getSocketState(businessType); if (!state) return; try { // 构建完整的WebSocket连接URL const query = new URLSearchParams(params).toString(); const url = `${WS_CONFIG.WS_BASE_URL}${path}${query ? `?${query}` : ''}`; // 关闭可能存在的旧连接,避免重复连接 if (state.socket) { state.socket.close(1000, `切换${businessType}连接`); state.socket = null; } // 创建新的WebSocket实例 state.socket = new WebSocket(url); console.log(`[WS-${businessType}] 正在连接: ${url}`); /** * 1. 连接成功打开事件处理 * 连接成功后:更新状态、停止重连、启动心跳、通知回调 */ state.socket.onopen = () => { state.isConnected = true; // 更新连接状态 stopReconnect(businessType); // 重连成功,停止重连定时器 startHeartbeat(businessType); // 启动心跳保活 // 通知连接成功 callback?.({ type: 'open', status: true, businessType // 携带业务类型识 }); console.log(`[WS-${businessType}] 连接成功 ✅`); }; /** * 2. 接收到服务器消息事件处理 * 处理服务端发送的消息:过滤心跳响应,分发业务消息 * @param {MessageEvent} event - 原始消息事件 */ state.socket.onmessage = (event) => { // 过滤心跳响应(服务端返回的'pong'消息) if (event.data === 'pong') { console.log(`[WS-${businessType}] 收到心跳响应: pong`); return; } let message = null; try { // 尝试解析JSON格式消息 message = JSON.parse(event.data); } catch (e) { // 解析失败时,将原始数据包装为准格式 message = { type: 'text', content: event.data, businessType // 携带业务类型识 }; } // 将消息分发给所有注册的回调函数(携带业务类型) message && messageCallbacks.forEach(cb => cb({ ...message, businessType }) ); }; /** * 3. 连接错误事件处理 * 当WebSocket连接发生错误时触发:更新状态、通知回调 * @param {Event} error - 错误事件对象 */ state.socket.onerror = (error) => { state.isConnected = false; // 更新连接状态 // 通知错误发生 callback?.({ type: 'error', error, businessType // 携带业务类型识 }); console.error(`[WS-${businessType}] 连接错误 ❌:`, error); }; /** * 4. 连接关闭事件处理 * 当WebSocket连接关闭时触发:更新状态、停止心跳、条件重连 * @param {CloseEvent} event - 关闭事件对象 */ state.socket.onclose = (event) => { state.isConnected = false; // 更新连接状态 stopHeartbeat(businessType); // 停止心跳保活 console.log(`[WS-${businessType}] 连接关闭 🚫 | 状态码: ${event.code}`); /** * 核心重连判断逻辑: * - 非主动关闭(code≠1000):表示意外断开 * - 用户已登录(currentUser存在):表示需要维持连接 * 同时满足以上条件时,启动自动重连机制 */ if (event.code !== 1000 && currentUser) { startReconnect(businessType, path, params, callback); } // 通知连接关闭 callback?.({ type: 'close', code: event.code, businessType // 携带业务类型识 }); }; } catch (e) { // 捕获初始化过程中的异常 callback?.({ type: 'error', error: e, businessType }); console.error(`[WS-${businessType}] 初始化失败:`, e); } }; // ====================== 公开API方法 ====================== /** * 初始化全局WebSocket连接(登录后调用) * 同时建立两个独立的连接:消息推送(pushMessage) + 聊天室(chatRoom) * @param {Object} user - 用户信息对象,必须包含userId属性 * @param {string|number} user.userId - 用户唯一识符 * @param {string} [user.nickName] - 用户昵称,可选 * @param {Function} [callback] - 连接状态回调函数 * @returns {void} */ export const initGlobalWebSocket = (user, callback) => { if (!user?.userId) { console.error('[WS] 初始化失败:用户信息不完整,缺少userId'); callback?.({ type: 'error', error: new Error('用户信息不完整') }); return; } // 缓存用户信息,用于重连时重新建立连接 currentUser = user; // 关闭所有旧连接,避免重复连接 closeGlobalWebSocket(); // 公共查询参数(两个连接共享) const commonParams = { userId: user.userId, nickName: user.nickName || '' }; /** * 1. 初始化消息推送连接 * 路径:/pushMessage * 用途:接收系统通知、个人消息等推送 */ initWebSocket( 'pushMessage', // 业务类型识 WS_CONFIG.BUSINESS_PATH.pushMessage, // 连接路径 commonParams, // 查询参数 (res) => { // 转发回调,并携带业务类型信息 callback?.({ ...res, businessType: 'pushMessage' }); } ); /** * 2. 初始化聊天室连接 * 路径:/chatRoom{userId}(如/chatRoom123) * 用途:实时聊天、群组消息等 */ initWebSocket( 'chatRoom', // 业务类型识 `${WS_CONFIG.BUSINESS_PATH.chatRoom}${user.userId}`, // 拼接userId到路径 commonParams, // 查询参数 (res) => { // 转发回调,并携带业务类型信息 callback?.({ ...res, businessType: 'chatRoom' }); } ); }; /** * 发送消息到指定业务的WebSocket服务器 * @param {string} businessType - 业务类型:pushMessage/chatRoom * @param {Object|string} data - 要发送的数据,可以是对象或字符串 * @returns {boolean} - 发送是否成功,true表示成功,false表示失败 */ export const sendWebSocketMessage = (businessType, data) => { const state = getSocketState(businessType); if (!state) return false; // 校验连接状态 if (!state.isConnected || !state.socket) { console.error(`[WS-${businessType}] 发送失败:WebSocket未连接`); return false; } try { // 格式化消息:字符串直接发送,对象转为JSON字符串 const msg = typeof data === 'string' ? data : JSON.stringify(data); state.socket.send(msg); console.log(`[WS-${businessType}] 消息发送成功:`, data); return true; } catch (e) { console.error(`[WS-${businessType}] 消息发送失败:`, e); return false; } }; /** * 主动关闭所有WebSocket连接 * 用于用户主动断开连接或退出登录等场景 * @param {number} [code=1000] - 关闭代码,1000表示正常关闭 * @param {string} [reason='主动关闭'] - 关闭原因描述 * @returns {void} */ export const closeGlobalWebSocket = (code = 1000, reason = '主动关闭') => { // 清空用户信息 currentUser = null; // 关闭所有业务连接 Object.keys(socketPool).forEach(businessType => { const state = getSocketState(businessType); if (state) { // 停止所有定时器 stopHeartbeat(businessType); stopReconnect(businessType); // 关闭WebSocket连接 state.socket && state.socket.close(code, reason); state.socket = null; state.isConnected = false; } }); console.log('[WS] 主动关闭所有连接'); }; /** * 注册全局消息回调函数(接收所有业务类型的消息) * 回调函数将收到带有businessType识的消息 * @param {Function} callback - 消息处理回调函数 * @returns {void} */ export const registerMessageCallback = (callback) => { // 验证回调函数有效性并避免重复注册 if (typeof callback === 'function' && !messageCallbacks.includes(callback)) { messageCallbacks.push(callback); } }; /** * 移除消息回调函数 * 用于清理不再需要的消息处理函数,避免内存泄漏 * @param {Function} [callback] - 要移除的回调函数,不传则清空所有回调 * @returns {void} */ export const unregisterMessageCallback = (callback) => { if (callback) { // 移除指定的回调函数 messageCallbacks = messageCallbacks.filter(cb => cb !== callback); } else { // 清空所有回调函数 messageCallbacks = []; } }; /** * 获取WebSocket连接状态 * @param {string} [businessType] - 业务类型(不传则返回所有业务状态) * @returns {boolean|Object} - 单个业务状态或所有业务状态对象 */ export const getWebSocketStatus = (businessType) => { // 返回指定业务类型的连接状态 if (businessType) { const state = getSocketState(businessType); return state ? state.isConnected : false; } // 返回所有业务类型的连接状态 const allStatus = {}; Object.keys(socketPool).forEach(type => { allStatus[type] = socketPool[type].isConnected; }); return allStatus; }; // ====================== 默认导出 ====================== /** * WebSocket工具模块默认导出对象 * 提供完整的多连接WebSocket管理功能 */ export default { initGlobalWebSocket, // 初始化全局WebSocket(建立多个业务连接) closeGlobalWebSocket, // 主动关闭所有WebSocket连接 sendWebSocketMessage, // 发送WebSocket消息到指定业务 registerMessageCallback, // 注册全局消息回调函数 unregisterMessageCallback, // 移除消息回调函数 getWebSocketStatus // 获取连接状态(支持单业务和全业务查询) }; <template> <div> <el-tooltip :content="noticeContent" effect="dark" placement="bottom"> <el-badge :value="noticeCount" class="right-menu-item hover-effect" :class="{ 'badge-custom': noticeCount > 0 }"> <i class="el-icon-message-solid" @click="toNoticePage"></i> </el-badge> </el-tooltip> </div> </template> <script> import { listWbNoticeMessage } from "@/api/websocket/WbNoticeMessage"; import { registerMessageCallback, unregisterMessageCallback } from '@/utils/websocket'; export default { name: "InfoBell", props: { refreshNoticeCount: { type: Boolean, default: false } }, data() { return { noticeContent: "", // 通知内容 noticeCount: 0, // 通知数量 socket: null, // WebSocket 实例 // 查询参数 queryParams: { pageNum: 1, pageSize: 10, title: null, content: null, type: null, senderId: null, senderName: null, receiverId: this.$store.state.user.id, receiverName: null, isRead: null, readTime: null, priority: null, targetUrl: null, bizType: null, bizId: null }, }; }, created() { this.getList(); }, mounted() { // 注册WS回调:处理通知类消息 this.noticeCallback = (message) => { this.getList(); }; registerMessageCallback((message) => { if (message.businessType === 'pushMessage') { this.noticeCallback } }); }, beforeDestroy() { unregisterMessageCallback(this.noticeCallback); }, watch: { refreshNoticeCount(val) { if (val) { this.getList(); } } }, methods: { /** 查询通知信息框列表 */ getList() { this.queryParams.isRead = 0; listWbNoticeMessage(this.queryParams).then(response => { this.noticeCount = response.total; this.noticeContent = `您有${this.noticeCount}条未读的信息`; console.log('this.noticeCount', this.noticeCount) }) }, /** 跳转到通知页面 */ toNoticePage() { this.$router.push("/websocket/pushMessage"); }, }, }; </script> <style lang="scss" scoped> ::v-deep .el-badge__content { margin-top: 9px; margin-right: 1px; } .badge-custom { animation: blink-animation 0.5s infinite alternate; } @keyframes blink-animation { 0% { opacity: 1; } 100% { opacity: 0.1; } } </style> 在这页面怎么使用,连接已经有了,只用管业务,初始化WebSocket连接已经在登录的时候连接过了
最新发布
12-09
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值