Pinia 不处理 WebSocket,需在 Store 中用 ref/reactive 显式声明 socket、readyState 等响应式字段;重连须基于 onclose 触发并清除定时器;消息需解析校验后分发至 typed actions;connect 前须检查 socket 状态避免重复连接。

Pinia 本身不处理 WebSocket 连接,它只负责状态同步和响应式管理;真正要封装 WebSocket,必须在 Pinia Store 内部手动创建 WebSocket 实例,并用 ref 或 reactive 包裹连接状态、重连控制、消息队列等关键字段——否则无法触发视图更新。
WebSocket 连接状态必须用 ref/ reactive 显式声明
很多人直接在 Store 里写 let socket = null,结果状态变化不响应。Pinia 的响应式机制只追踪通过 state 返回的属性,或 ref/reactive 显式声明的变量。
- ✅ 正确做法:在
state中返回socket: ref(null)、readyState: ref(WebSocket.CLOSED) - ❌ 错误写法:
let socket = null放在actions外部,或直接赋值给普通对象字段(如state.socket = new WebSocket(...)) - 注意:
WebSocket.READY_STATE是只读属性,不能直接赋值;要用ref手动同步,比如在onopen里执行readyState.value = WebSocket.OPEN
重连逻辑必须解耦定时器与 Store 生命周期
自动重连不是“开个 setInterval 就完事”,容易在组件卸载后仍触发回调,造成内存泄漏或重复连接。
- 重连应基于
onclose触发,而非轮询;首次失败后延迟 1s,后续指数退避(如 1s → 2s → 4s) - 必须在
store.$dispose()或onUnmounted时清除所有定时器(clearTimeout(rec)),否则重连任务持续运行 - 避免在
onerror中盲目重连——很多错误(如 401、URL 无效)是永久性问题,重连只会刷屏报错
消息分发要用 defineStore 的 actions + 类型守卫
服务端推送的消息格式不统一,直接往 state.messages.push(event.data) 会导致类型混乱、UI 渲染异常。
立即学习“前端免费学习笔记(深入)”;
- 推荐在
onmessage回调中先做JSON.parse,再用switch (data.type)分发到不同 action(如handleChatMsg、handleSystemEvent) - 每个 action 内部做字段校验(例如检查
data.conversation_id是否存在),防止脏数据污染 state - 不要把原始
event对象存进 state —— 它含不可序列化字段(如event.target),会影响 Pinia 持久化或 DevTools 调试
最易被忽略的一点:WebSocket 实例不能跨页面复用(比如 A 页面关闭了 socket,B 页面又调用 store.connect()),但 ref(socket) 在 Store 卸载后不会自动清空。务必在每次 connect() 前加判断:if (socket.value && socket.value.readyState === WebSocket.OPEN) return,否则可能创建多个并行连接却只保留最后一个引用。


















