vue中网络断开与重连提示应监听websocket/socket.io连接状态事件而非navigator.online,结合心跳检测、navigator.connection辅助预判及pinia统一管理状态实现精准可靠通知。

Vue 中实现网络断开与重连的实时提示通知,关键不是监听“网络是否在线”这个布尔值,而是监听 WebSocket 或 Socket.io 连接本身的状态变化,并结合浏览器网络 API 做分层判断。单纯依赖 navigator.onLine 容易误报(比如网线插着但服务器宕机),真正可靠的是连接实例自身的事件流。
监听 socket 实例的核心生命周期事件
无论你用的是原生 WebSocket、ReconnectingWebSocket,还是 socket.io-client,它们都暴露标准的连接状态事件。在 Vue 组件或组合式函数中直接响应这些事件,就能触发通知:
- connect / open:连接成功时,隐藏“离线提示”,可播放轻量音效或显示绿色状态徽标
-
disconnect / close:连接意外关闭(非主动调用
close()),立即显示 Toast 提示:“连接已断开,正在尝试恢复…” - connect_error / error:捕获具体错误信息,区分是 DNS 失败、拒绝连接还是 TLS 握手失败,便于前端分类提示(如“服务器暂不可用” vs “网络未连接”)
- reconnect_attempt:每触发一次重连尝试,更新提示文案为“第 X 次重连中…”,避免用户误以为卡死
用 navigator.connection 辅助预判弱网风险
navigator.onLine 不够细,但 navigator.connection.effectiveType 和 .downlink 可以提前干预:
- 当
effectiveType === 'slow-2g'或downlink 时,自动降低消息发送频率、禁用图片预加载,并在 UI 角落显示“弱网模式已启用”小标签 - 监听
connection.addEventListener('change', handler),网络类型切换时动态调整重连策略(例如从 2s 间隔延长至 5s,减少无效请求) - 注意:该 API 在部分 iOS Safari 和旧版 Chrome 中受限,需做存在性判断,不作为主逻辑依赖
统一管理连接状态并广播通知
避免每个组件重复监听 socket 事件。推荐在 Pinia store 中集中维护连接状态,并通过 computed 或 $subscribe 暴露响应式信号:
- store 定义
isConnected: ref(false)、reconnectCount: ref(0)、lastError: ref(null) - 在 socket 的
connect回调中设isConnected.value = true;在disconnect中设为false并清空错误 - 组件内使用
const { isConnected, lastError } = useSocketStore(),配合v-if="!isConnected"控制离线 Banner 显示 - 全局 Toast 通知由 store 内部调用
useMessage().warning(...)触发,确保一次断连只弹一次,不重复打扰
主动心跳检测防“假连”
TCP 连接可能维持但实际无法通信(如 NAT 超时、防火墙静默丢包)。需主动发心跳保活并验证响应:
- 连接建立后,每 15 秒向服务器发送
{ type: 'ping' }消息 - 服务端必须回传
{ type: 'pong' };前端设置 5 秒超时,超时即视为“假连”,主动触发 disconnect 流程 - 此时通知文案应更明确:“网络连接异常,请检查网络或稍后重试”,而非模糊的“已断开”
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











