websocket应在app.vue或main.ts中全局唯一初始化,通过provide/inject或globalproperties暴露;onmessage需解耦ui,用事件总线或pinia派发通知,并控制弹窗位置、时长、去重及心跳重连。

WebSocket连接必须在App.vue或main.ts中初始化
全局弹窗依赖消息的“无处不在”,但WebSocket实例不能每个页面都new一次,否则会触发多个并发连接、状态错乱、内存泄漏。实际项目里最稳妥的做法是:只在应用入口(App.vue的mounted钩子,或main.ts中Vue应用挂载前)创建唯一WebSocket实例,并用provide/inject或globalProperties暴露给所有组件。
常见错误包括:
- 在某个业务页面里
new WebSocket(),跳转后未close(),再进页面又建一个——后端看到的是多个重复连接ID - 把
onmessage逻辑写在组件内部,导致页面卸载后回调还在执行,this指向丢失或触发已销毁组件的setState - 没做重连兜底,网络抖动时连接断开,后续消息彻底丢失
推荐结构:const socket = new WebSocket(url) → 绑定onopen/onmessage/onclose → 将socket存入app.config.globalProperties.$ws(Vue 3)或Vue.prototype.$ws(Vue 2)。
onmessage里别直接调Notification,要走事件总线或Pinia状态派发
Notification(如Element Plus的ElNotification)或ElMessage是UI层,而onmessage属于网络层。两者硬耦合会导致:无法统一控制弹窗堆叠顺序、不能拦截敏感消息、测试时难以 mock、升级通知样式时要翻遍所有onmessage回调。
应该把消息接收和UI展示解耦:
分析 Vue 3 Composition API 使用情况——审计响应式模式、可组合函数设计、ref 与 reactive 的选择、计算属性、watcher 使用及组件……
- 在
onmessage中只做解析、校验、基础过滤(比如忽略空消息、过期时间戳) - 用
mitt或defineEmits(组合式API)广播事件,例如bus.emit('notification:push', payload) - 或写入Pinia store的
notifications数组,由独立的NotificationManager.vue监听并渲染 - 避免在
onmessage里直接调用ElNotification.success({ ... })——这是最常被踩的坑
弹窗位置、堆叠与关闭策略必须显式控制
浏览器原生Notification API默认在系统右下角,但受限于权限且样式不可控;前端组件如ElNotification默认在右上角,且多个实例会垂直堆叠。问题在于:WebSocket可能连续推送3条消息,用户还没关第一个,后面两个就叠在下面,容易漏看高优先级通知。
关键参数要手动设:
-
position:固定为'top-right'或'bottom-right',避免不同页面配置不一致 -
duration:重要通知设0(永驻),普通消息设4500,别用默认值 -
group或id:每条通知带唯一id,方便后续用ElNotification.close(id)主动关闭旧通知 - 加个简单去重逻辑:5秒内相同
title + content的消息,跳过弹窗(防刷屏)
Vue 3中useWebSocket自定义Hook需处理unmount自动清理
如果用组合式API封装useWebSocket,必须在onUnmounted里socket.close(),否则组件销毁后socket仍保持连接,onmessage回调还会往已卸载组件里写状态,报Cannot update a component while unmounting错误。
实操要点:
- 用
ref存WebSocket实例,不是let socket局部变量 - 在
onUnmounted中判断socket.value?.readyState === WebSocket.OPEN再close() - 不要在
onmessage里直接console.log或alert——这些只是调试手段,上线前必须删掉或替换为日志服务上报 - 心跳包逻辑(
ping/pong)建议单独抽成useWebSocketHeartbeat,和消息收发解耦
真正难的不是连上WebSocket,而是让通知在页面跳转、组件卸载、网络中断、多标签页等边界场景下依然稳定可靠。多数线上事故,都出在重连失败后没降级到轮询,或通知ID生成规则冲突导致重复弹窗。这些细节比语法更重要。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










