pinia本身不内置网络监听能力,需结合navigator.online事件与pinia store手动封装:在main.ts中注册online/offline全局监听,store中用ref管理isonline状态,组件watch该状态做ui提示或请求拦截,并辅以心跳检测弥补online局限性。

Pinia 本身不内置网络状态监听能力,它只负责状态管理。要实现全局的“网络断开/重连”状态感知与响应,需要结合浏览器原生事件(online/offline)+ Pinia store 进行手动封装。核心思路是:用 Pinia 存储当前网络状态,并在事件触发时自动更新;业务组件或逻辑可订阅该状态,做 UI 提示、请求拦截、队列重发等处理。
1. 创建网络状态 Store
定义一个专门管理网络连接状态的 Pinia store:
- 使用
ref存储布尔值isOnline,初始值取navigator.onLine - 在
onMounted(或 store 初始化时)监听window.online和window.offline事件 - 确保卸载时移除事件监听,避免内存泄漏
示例代码:
import { defineStore } from 'pinia'<br>export const useNetworkStore = defineStore('network', () => {<br> const isOnline = ref(navigator.onLine)<br><br> const handleOnline = () => (isOnline.value = true)<br> const handleOffline = () => (isOnline.value = false)<br><br> // 监听事件(建议在插件或 main.ts 中统一注册)<br> onMounted(() => {<br> window.addEventListener('online', handleOnline)<br> window.addEventListener('offline', handleOffline)<br> })<br><br> onUnmounted(() => {<br> window.removeEventListener('online', handleOnline)<br> window.removeEventListener('offline', handleOffline)<br> })<br><br> return { isOnline }<br>})
2. 在应用启动时注册全局监听
不要把事件监听写在 store 内部的生命周期钩子中(因为 Pinia store 不是组件,没有 onMounted)。更稳妥的做法是在 main.ts 或自定义插件里初始化:
- 创建 store 实例
- 立即绑定
online/offline事件 - 可选:触发一次初始状态同步(如发送 toast 提示)
例如:
import { createApp } from 'vue'<br>import { createPinia } from 'pinia'<br>import App from './App.vue'<br>import { useNetworkStore } from './stores/network'<br><br>const app = createApp(App)<br>const pinia = createPinia()<br>app.use(pinia)<br><br>// 全局注册网络事件<br>const networkStore = useNetworkStore()<br>window.addEventListener('online', () => {<br> networkStore.isOnline = true<br> // 可在此触发重试队列、提示用户等<br>})<br>window.addEventListener('offline', () => {<br> networkStore.isOnline = false<br>})
3. 结合请求层做智能响应
仅展示状态不够,关键是要让业务“感知并行动”。常见做法:
- 在 Axios 拦截器中检查
useNetworkStore().isOnline,若为false则直接 reject 并抛出特定错误(如NetworkError) - 维护一个离线请求队列(如用数组暂存 config),待重连后自动重发
- 在页面级组件中 watch
isOnline,动态显示 toast 或禁用按钮 - 对关键操作(如提交表单)加二次确认:“当前网络不可用,是否暂存本地?”
4. 注意事项与边界情况
浏览器的 navigator.onLine 有局限性:
- 它只检测设备是否连上网络(比如 WiFi 开关打开),**不保证能访问服务器**。可能连着网但 DNS 故障、代理异常、服务宕机
- 移动端切后台再切回前台时,状态可能未及时更新,建议配合定时心跳请求(如每 30s GET /health)做二次验证
- 某些 PWA 场景需额外处理 service worker 缓存策略,避免离线时返回过期数据










