关键在于让 vue 响应式系统自然感知变化并精准重绘:用 reactive(map) 管理动态列表、封装 websocket 为统一服务、高频更新需防抖+批量+虚拟滚动、首次加载须先拉全量再启增量监听。

关键不是“收到就赋值”,而是让 Vue 的响应式系统自然感知变化并触发精准重绘。核心在于数据绑定方式、更新粒度控制和连接状态协同。
用 reactive 或 ref 管理状态,但别直接替换整个对象
如果看板展示的是一个动态列表(如在线用户、实时订单),推荐用 reactive 包裹一个对象或 Map,而不是每次用 ref([]) 然后全量赋值:
- 用
const dataMap = reactive(new Map())按 ID 存储条目,收到增量更新时只改对应 key:dataMap.set(id, newData) - 若结构较深(如嵌套的统计指标),确保整个顶层对象是 reactive 的,避免只对子属性做 .value 赋值导致响应失效
- 模板中通过
v-for遍历[...dataMap.values()]或用computed转为数组,Vue 会自动追踪 Map 内容变更
把 WebSocket 封装成独立服务,组件只订阅关心的数据类型
不建议在每个看板组件里写 new WebSocket()。应抽离为可复用服务(如 useRealtimeData()),统一处理连接、重连、错误和消息分发:
- 服务内部用
emit(或mitt)广播事件,例如bus.emit('order:update', payload) - 看板组件用
onMounted(() => bus.on('order:update', updateLocal))订阅,卸载时off清理,避免内存泄漏 - 服务暴露
send()和status(如ref('connected')),让 UI 可显示“正在重连中”等状态
处理高频推送:防抖 + 批量合并 + 虚拟滚动
行情、监控类看板常面临每秒数十条更新,直接逐条触发渲染会导致卡顿:
- 对同一数据源的连续推送,用
setTimeout防抖(如 100ms 内只取最后一次)再更新 - 后端支持时,请求带游标(
?last_id=123)避免重复收老数据;前端缓存最近 50 条 ID,过滤已处理项 - 列表过长时,配合
vue-virtual-scroller或 ECharts 的大数据模式,只渲染可视区域
初始加载与增量同步必须配合
WebSocket 推送的是变更,不是快照。用户首次打开看板时,必须先拉取全量数据,再开启监听:
- 在
onMounted中先发一次 HTTP 请求获取当前状态(如GET /api/dashboard) - 拿到后初始化
dataMap,再调用initSocket()连接 WebSocket - 这样既保证首屏完整,又确保后续所有更新都是准确的增量,不会出现“刚进来看板空了一半”的情况
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











