onshow是页面每次显示时的正确触发入口,包括返回、切前台等场景;需将刷新逻辑移至此并自行防重复;精确判断来源页用getcurrentpages;跨页通信推荐eventchannel;拦截返回键需区分from值。

onShow 是返回时触发函数的正确入口
页面返回时不执行 onLoad,这是设计行为,不是 bug。真正每次“显示”都会触发的是 onShow —— 包括从后台切前台、从其他页面返回、甚至小程序被拉起时。只要逻辑需要“返回即响应”,就必须把核心代码从 onLoad 挪到 onShow。
常见错误是把数据刷新、状态校验、权限检查全写在 onLoad 里,结果用户从支付页返回订单页,界面还是旧数据。
-
onShow触发时机:页面进入前台、uni.navigateBack返回、uni.switchTab切回、App 从后台恢复 - 它不区分“是否首次加载”,所以需自行判断是否要重复请求(比如加
loading锁或节流) - H5 和 App 端行为一致;微信小程序中若用了
redirectTab或reLaunch,onShow仍会触发,但页面栈已重置
需要“仅返回时”才执行?用 getCurrentPages 判断上一页
如果业务要求严格区分“首次打开”和“从 B 页面返回”,不能靠 onShow 无差别执行,就得手动查栈。
getCurrentPages() 返回当前所有页面实例数组,最后一个元素是当前页,倒数第二个就是上一页。
- 示例:当前页是
pages/order/detail,想确认是不是从pages/order/list进来的 const pages = getCurrentPages(); const prevPage = pages[pages.length - 2]; if (prevPage?.route === 'pages/order/list') { this.refreshData(); }- 注意:小程序平台(如微信)中,
route值不含.vue后缀,且路径为注册时的相对路径(如pages/order/list) - 该方式在 H5 端也有效,但不适用于
redirectTo或reLaunch跳转后的场景(因为上一页已被销毁)
跨页面精准通信:eventChannel 比全局事件更可靠
当 A 页跳转到 B 页,B 页完成操作后主动通知 A 页刷新,用 eventChannel 是官方推荐方案,比 uni.$emit 更可控、无内存泄漏风险。
关键限制:channel 必须在 A 页的 onLoad 中绑定,延迟到 onShow 就失效 —— 因为 channel 实例只在页面初始化时存在。
- A 页跳转:
uni.navigateTo({ url: '/pages/b/b', events: { refresh: () => this.getData() } }); - A 页监听(必须在
onLoad):this.getOpenerEventChannel().on('refresh', () => this.getData()); - B 页返回前:
this.getOpenerEventChannel().emit('refresh'); - 不支持多次 emit 同名事件后自动解绑,建议在
onUnload手动off防止残留
拦截物理返回键并跳指定页面?onBackPress + from 判断
用户点左上角返回按钮或 Android 物理键时,onBackPress 会被触发,且 options.from === 'backbutton';而代码调用 uni.navigateBack 时,from 是 'navigateBack'。
这个区分决定了你是否要拦截:程序触发的返回通常不该干预,用户触发的才可定制跳转逻辑。
- 典型场景:阅读页返回时,根据来源跳书城/书架/首页,而不是默认回退
- 示例:
onBackPress(options) { if (options.from !== 'backbutton') return; const pages = getCurrentPages(); const prevPage = pages[pages.length - 2]; if (prevPage?.route === 'pages/bookstore/index') { uni.redirectTo({ url: '/pages/bookstore/index' }); return true; } } - 返回
true表示已处理,阻止默认回退;返回false或不返回则走默认逻辑 - 注意:iOS 导航栏返回按钮在某些版本下可能不触发
onBackPress,需结合原生插件或自定义导航栏兜底
最易被忽略的点是:eventChannel 的生命周期绑定时机、onShow 的重复执行风险、以及 onBackPress 对不同 from 值的误判。业务越复杂,越要先厘清“谁触发”“何时触发”“是否该拦截”这三个问题,而不是堆逻辑。










