uni.getNetworkType() 返回 none 仅表示当前无网络,并非断网的可靠判断依据;需配合 uni.onNetworkStatusChange 实时监听状态变化,并在 onAppShow 中手动检测修复前台恢复场景。

uni.getNetworkType() 返回 none 就代表断网?不完全是
很多开发者一上来就用 uni.getNetworkType() 判断网络状态,但这个 API 是**一次性快照**,不会自动监听变化。调一次返回 none 只能说明「此刻没网」,无法捕获「从有到无」的切换事件。真正要监听断开,必须配合 uni.onNetworkStatusChange —— 它才是 uni-app 唯一支持的实时网络状态变更监听器。
注意:该监听器在 App 端(iOS/Android)和微信小程序中稳定可用;H5 端依赖 navigator.onLine,存在兼容性问题(比如 Chrome 下拔网线后可能延迟数秒才触发);支付宝小程序暂不支持此 API,需降级处理。
- 务必在
App.vue的onLaunch和onShow中调用uni.onNetworkStatusChange注册,避免页面级监听被销毁后漏掉事件 - 不要在组件
onUnload里手动off,因为全局监听不应随单个页面卸载而取消 - 首次进入时,需主动调用
uni.getNetworkType()获取初始状态,否则监听器触发前页面不知道当前是否有网
如何避免重复弹出「网络已断开」提示?
断网提示最让人烦躁的不是没提示,而是反复弹、连环弹。根本原因是:网络抖动时,onNetworkStatusChange 可能在几秒内触发多次 { isConnected: false },如果每次触发都 uni.showToast 或 uni.showModal,用户会疯。
解决方案是加节流 + 状态锁:
- 用一个全局变量(如
window.__networkAlertLocked)标记「正在提示中」,触发后设为true,3 秒内再次触发直接 return - 提示关闭后(如 toast 自动消失或用户点击确定),再把锁设回
false - 更稳妥的做法是只在
isConnected从true变为false的瞬间提示,需缓存上一次状态做比对
示例关键逻辑:
let lastConnected = true
uni.onNetworkStatusChange((res) => {
if (res.isConnected === false && lastConnected === true) {
if (!window.__networkAlertLocked) {
window.__networkAlertLocked = true
uni.showToast({
title: '网络已断开',
icon: 'none',
duration: 2000
})
setTimeout(() => {
window.__networkAlertLocked = false
}, 3000)
}
}
lastConnected = res.isConnected
})
全局提示组件怎么挂载才不侵入业务页面?
不能让每个页面都 import 提示组件并 v-if 控制显隐——这违背「全局」本意,也容易漏写。正确方式是用 uni.$emit / uni.$on 通信 + uni.createSelectorQuery 动态插入 DOM(App/H5)或使用原生层遮罩(小程序)。
但最轻量且跨端兼容的做法是:在 App.vue 的 <template></template> 底部直接写一个固定定位的提示条,用 v-show 控制,由全局状态驱动:
- 定义响应式数据
networkTipVisible: false和networkTipText: ''在App.vue的data - 在
onNetworkStatusChange回调中,仅修改这两个 data 字段,不调用任何 UI API - 组件模板里用
<view class="network-tip" v-show="networkTipVisible">{{ networkTipText }}</view>,样式设为position: fixed; top: 0; width: 100%; z-index: 9999;
这样所有页面共享同一份 DOM,无需额外 import,也不依赖 vuex 或 pinia。
App 端后台切前台时网络状态没更新?
App(尤其是 iOS)从后台切回前台时,onNetworkStatusChange 不一定自动触发,导致页面仍显示「断网」状态,实际网络已恢复。这是因为系统未主动上报状态变更。
必须手动补一手检测:
- 监听
uni.onAppShow,在回调里立即调用uni.getNetworkType() - 拿到结果后,与当前缓存的网络状态比对,若不一致,则触发一次模拟的 status change 事件(即手动执行一遍监听器里的逻辑)
- 注意:不要在
onAppShow里重复注册onNetworkStatusChange,否则造成监听器叠加
这是 App 端最容易忽略的边界场景——用户以为「回到前台=自动重连」,但框架不会替你刷新状态。


















