双击退出功能必须在app.vue中实现,android可真退出,ios和h5仅支持提示或跳转;需用时间戳判断双击、过滤backbutton事件、仅首页启用、平台条件编译包裹原生api调用。

必须写在 App.vue 里,不能放页面组件中;Android 可真退出,iOS 和 H5 只能降级提示或跳转。
onBackPress 必须在 App.vue 中声明并立即 return true
页面级的 onBackPress 只对当前页生效,而“双击退出”是全局行为——用户从二级页返回首页后双击,逻辑仍要起作用。所以只能写在 App.vue 的生命周期里。
- 入口第一行就要
return true,否则系统会先执行默认返回(比如跳上一页),弹窗都来不及显示 - 错误写法:
if (res.confirm) { plus.runtime.quit(); }再return true—— 用户还没点确认,页面已退 - 正确顺序:先拦截(
return true),再异步弹窗,再根据用户操作决定是否调plus.runtime.quit() - 务必加
options.from === 'backbutton'过滤,避免干扰uni.navigateBack()等 JS 调用
时间戳判断比计数器更稳,阈值设 2000ms
双击不是“按两次”,而是“两次间隔是否小于阈值”。用时间戳比 this.clickCount++ 更可靠,避免连按三次导致状态错乱。
- 变量
this.lastBackTime必须挂载在App.vue实例上(如data或export default外层this),不能是局部变量 - 每次触发
onBackPress时取Date.now(),与this.lastBackTime比较差值 - 差值 uni.showToast({ title: '再按一次退出' })
- 清零必须用
setTimeout(() => { this.lastBackTime = 0; }, 2000),箭头函数确保this绑定正确
平台差异必须包裹条件编译
plus.runtime.quit() 仅 Android 有效,iOS 静默失败,H5 根本不触发 onBackPress。不加判断会报错或行为异常。
- Android:直接调
plus.runtime.quit() - iOS:改用
uni.showToast({ title: '双击 Home 键退出', icon: 'none' }),或跳转系统设置(plus.runtime.launchApplication({ action: 'QUIT' })) - H5:不走
onBackPress,需额外监听history.back()降级,但无法真正退出 - 所有原生 API 调用必须用
if (process.env.UNI_PLATFORM === 'app-plus')包裹
非首页要禁用该逻辑
子页、表单页、详情页等不该拦截返回键,否则用户无法正常后退。只应在栈底(即首页)启用双击退出。
- 用
getCurrentPages().length === 1判断是否在页面栈最底层 - tabbar 页面可能因
uni.navigateBack()失败而 fallback 到plus.runtime.quit(),需单独处理 - 若当前页是登录页、协议页等不可退页面,也建议临时禁用
最容易被忽略的是:清零定时器里的 this 绑定、options.from 过滤、以及非首页的拦截开关——这三个点漏掉任何一个,都会导致用户在子页退不了,或者首页点了没反应。











