真正有效的本地App版本号只能通过plus.runtime.version获取,它对应manifest.json的versionName;需用#ifdef APP-PLUS条件编译、try/catch容错,并fallback至uni.getSystemInfoSync().version加正则校验。

怎么拿到真正有效的本地 App 版本号
别信 uni.getSystemInfoSync().version,它在 iOS 返回系统版本,在 Android 常为空或不可靠;真正能用的只有 plus.runtime.version,但它只在 5+ App 环境(即真机或自定义基座)下存在。
必须加容错处理:
- 先判断
uni.getSystemInfoSync().platform是否为"ios"或"android" - 再 try/catch 调用
plus.runtime.version,失败则 fallback 到uni.getSystemInfoSync().version并做正则校验(如/^\d+\.\d+\.\d+$/) - 小程序、H5、模拟器环境直接跳过整套逻辑,否则会报
Cannot read property 'version' of undefined
为什么 cover-view 弹窗必须放 App.vue 底部 + 延迟渲染
cover-view 是唯一能盖过 map、video、摄像头等原生组件的容器,但它的渲染时机极敏感——同步挂载在 onLaunch 里,iOS 下大概率“闪一下就消失”。
正确做法是:
- 把弹窗结构写在
App.vue底部,用v-if="showUpdateModal"控制显隐 - 检查完版本后,用
setTimeout(() => { this.showUpdateModal = true }, 100)延迟触发,避开 Vue 初始化和 plus 注入耗时 - 安卓上点击空白区域无法关闭,是因为
cover-view默认不响应事件,必须显式加bindtap="closeModal"并手动控制状态
下载进度条怎么监听且不丢帧
别用 uni.downloadFile,它不支持进度回调;必须用 H5+ 的 plus.downloader.createDownload,并绑定 statechanged 事件。
关键细节:
- 下载任务创建后立即监听:
downloadTask.addEventListener('statechanged', (task, status) => { ... }) - 只在
task.state === 2(正在下载)时更新进度,避免其他状态干扰 -
this.progress = Math.round((task.downloadedSize / task.totalSize) * 100)必须四舍五入取整,否则小数频繁触发视图重绘,导致卡顿 - iOS 不支持静默安装,下载完只能跳 App Store;Android 调
plus.runtime.install(task.filename)后,无法监听安装是否成功,需额外注册原生广播接收器
强制更新时怎么锁死用户操作流
不是弹个模态框就叫强制——得从路由、返回键、遮罩层三处同时拦截。
具体要做的:
- 服务端返回
forceUpdate: true且版本比对结果为需更新后,立刻设置全局状态(如 Vuex 或 pinia 的isUpdateBlocked = true) - 在路由守卫中判断该状态,若为
true,则uni.redirectTo({ url: '/pages/update/force' }),该页面只渲染弹窗 + 阻止返回 - 安卓用
plus.key.addEventListener('backbutton', () => {}, false)拦截物理返回键;iOS 手势返回无法完全禁用,但可配合全屏遮罩 + 禁用所有交互元素 - 遮罩层必须用
cover-view实现,否则会被原生组件穿透,用户仍能点到背后按钮
最容易被忽略的是:iOS 真机必须先调 uni.getProvider({service: 'update'}) 确认支持,否则后续所有 plus.downloader 调用都会静默失败。


















