不能关闭确认对话框是因为它由开发者在onbackpress中主动调用uni.showmodal实现;需删除该行代码或修改判断逻辑,如仅对物理返回键、非首页、有未保存草稿等条件弹窗,并注意h5和ios侧滑手势不触发onbackpress。

不能“关闭”确认对话框——它本就不是 uni-app 自带的,而是你代码里主动弹的。 你看到的“退出确认”,100% 是你自己在 onBackPress 里调了 uni.showModal。想让它不出现,删掉那行弹窗代码就行;想让它只在特定条件出现,得改判断逻辑。
onBackPress 里别无脑弹 uni.showModal
很多项目一上来就在 onBackPress 开头写:
onBackPress() {
uni.showModal({ title: '退出应用', content: '确定要退出吗?' })
return true
}
这会导致每次按返回键都弹,毫无区分。真实场景需要分情况处理:
- 只对物理返回键(
options.from === 'backbutton')拦截并弹窗,其他来源(比如uni.navigateBack()调用)直接放行 - 首页才允许退出,子页面一律
uni.navigateBack() - 用户已登录但未保存草稿,才弹确认;否则直接退
- 双击退出时,第一次不弹窗、只记时间戳,第二次才弹
App.vue 中的双击退出逻辑必须手动控制弹窗时机
双击退出不是系统行为,是靠你自己存时间戳实现的。关键点在于:uni.showModal 必须放在第二次点击的分支里,且必须在函数入口立刻 return true 拦截,否则页面会先退掉:
onBackPress(options) {
if (options.from !== 'backbutton') return // 只响应物理键
<p>const now = Date.now()
if (now - this.lastBackTime {
if (res.confirm) plus.runtime.quit()
}
})
this.lastBackTime = 0 // 重置
return true // 入口已拦,此处只是补全逻辑
} else {
// 第一次点击:仅记录时间,不弹窗
this.lastBackTime = now
return true // 同样必须拦,否则页面退了,第二次就没机会触发了
}
}</p>
注意:this.lastBackTime 必须定义在 data 或 setup 的响应式对象里,不能是局部变量。
H5 平台根本不会进 onBackPress,别在这儿加弹窗
浏览器地址栏后退、Alt+←、手势返回,全部绕过 onBackPress。你在 App.vue 里写的弹窗逻辑对 H5 完全无效。如果 H5 也想有退出确认,得换思路:
- 监听
window.history变化(不可靠,兼容差) - 用
beforeunload提示「页面有未保存内容」(仅限表单修改场景) - 更实际的做法:H5 不做退出确认,只做「刷新前提示」,用
window.addEventListener('beforeunload', ...) - 千万别在 H5 里尝试
history.back()+ 弹窗,浏览器不允许异步阻断返回操作
最常被忽略的一点:iOS 侧滑返回手势从不触发 onBackPress,哪怕你在 pages.json 里关了 "popGesture": "close",也只是让侧滑失效,并不会把它转成 backbutton 事件。真要统一管控,只能放弃原生手势,全走自定义导航栏按钮。











