双击退出逻辑必须写在App.vue中,入口立即return true,用时间戳而非计数器判断间隔,仅首页启用并做好平台兼容性处理。

onBackPress 必须写在 App.vue 里,不能放页面组件中
页面级的 onBackPress 只影响当前页,而“双击退出”是跨页面行为——用户从二级页返回首页后双击,逻辑必须还在。所以必须下沉到 App.vue 的生命周期里。若写在 pages/index/index.vue 这类业务页中,切到其他页面后该逻辑就彻底失效。
入口立刻 return true,否则弹窗没显示页面已退回
这是最常踩的坑:onBackPress 函数入口不立即 return true,系统就会直接执行默认返回(比如跳上一页),uni.showModal 都来不及触发。
- ✅ 正确顺序:先取
Date.now()→ 判断间隔 → 满足双击条件则调plus.runtime.quit()并return true - ❌ 错误写法:
if (res.confirm) { plus.runtime.quit(); }后再return true—— 用户还没点确认,页面已经退了 - 所有分支都必须
return true,包括提示“再按一次退出”的分支,否则拦截失败
时间戳 + 2000ms 清零,别用计数器
用 this.lastBackTime 存时间戳比用 this.clickCount++ 更稳:避免连按三次导致状态错乱,也规避清零时机难把握的问题。
-
this.lastBackTime必须挂载在App.vue实例的data中,不能是局部变量 - 阈值设为
2000是经验值,太短易误触,太长体验拖沓 - 清零必须用
setTimeout(() => { this.lastBackTime = 0; }, 2000),箭头函数确保this绑定正确;不能用function() { this.lastBackTime = 0; },否则this指向window
非首页禁用双击逻辑,避免拦死正常后退
如果用户在表单页、详情页等子页双击返回键,你仍执行退出逻辑,会导致无法正常返回上一页。应只在栈底(即首页)启用该逻辑。
- 用
getCurrentPages().length === 1判断是否在页面栈最底层 - 搭配
options.from === 'backbutton'过滤,避免干扰uni.navigateBack()等 JS 调用 -
plus.runtime.quit()仅 Android 有效,iOS 和 H5 需降级:process.env.UNI_PLATFORM === 'app-plus'条件编译包裹,否则 H5 小程序会报错
return true 的执行时机、平台兼容性判断这三点最容易被忽略。尤其是 iOS 上静默失败、H5 完全不触发,不加条件编译就上线,很可能让测试同学反复问“为什么点两下没反应”。


















