onShow 刷新需精准控制时机与范围:首次进入由 onLoad 处理,onShow 中应判断 dataLoaded、重置分页/搜索状态、加 loading 锁防并发;事件总线须 onUnload 配对卸载;eventChannel 适用于 navigateTo 场景;getCurrentPages 直接改 data 高风险,优先用 setData 或状态管理。
直接在 onshow 里拉数据是最稳妥的起点,但盲目搬移逻辑反而会引发重复请求、分页错乱或状态残留——关键不是“要不要刷”,而是“什么时候刷、刷什么、怎么避免副作用”。
onShow 刷新:为什么它常被写错
很多人把 onLoad 的全部逻辑复制进 onShow,结果页面一显示就发两次请求(onLoad 一次 + onShow 一次),或者下拉刷新后返回,页码还是上次的 this.page = 2,导致新数据漏掉。
- 只在真正需要时才触发:首次进入已由
onLoad处理,onShow中应加判断,比如用this.dataLoaded标志位控制 - 重置分页/筛选状态:若页面支持搜索或分页,
onShow开头应显式设this.page = 1、this.searchKey = '' - 避免 loading 冲突:多个
onShow快速触发(如切后台再切回)可能并发请求,建议加this.loading锁或节流 - H5 环境下,iOS 微信 WebView 有时会延迟触发
onShow,不要依赖setTimeout补救,优先检查是否误用了自定义navigationStyle: custom却没手动调uni.navigateBack()
事件总线(uni.$emit / uni.$on):必须配对卸载
当你需要“仅编辑后才刷新”,而不是每次返回都刷,事件总线是更精准的选择。但它极易因 onUnload 漏掉 uni.$off 导致内存泄漏和多次触发。
- 监听必须写在
onLoad或mounted,但卸载必须严格对应写在onUnload(不是onHide) - 传函数引用,别传匿名函数:
uni.$on('refreshList', this.handleRefresh),然后uni.$off('refreshList', this.handleRefresh) - 不要在
onShow里重复uni.$on,否则每次显示都新增监听器 - 真机调试时,若发现事件触发两次,大概率是上一页实例没被销毁(比如用了
redirect而非navigateBack),或onUnload根本没执行(页面栈异常)
eventChannel:适合跳转即通信的场景
如果你是从 A 页跳到 B 页(uni.navigateTo),且 B 页操作完要立刻通知 A 页刷新,eventChannel 比全局事件总线更轻量、更可控——它天然绑定跳转关系,不跨页面污染。
- A 页跳转时创建 channel:
uni.navigateTo({ url: '/pages/b/b', events: { refresh: () => this.getData() } }) - B 页只能在
onLoad中通过this.getOpenerEventChannel()获取 channel,并且必须在onLoad里调.on('refresh', ...);放到onShow就失效 - B 页返回前调
this.getOpenerEventChannel().emit('refresh'),A 页监听函数立即执行 - 优势是无需手动管理生命周期,劣势是仅适用于
navigateTo场景,不适用于原生导航栏返回或switchTab
getCurrentPages 直接改 data:高风险但有时不得不用
当 eventChannel 不适用(比如从 tabBar 页面跳入)、事件总线又因架构限制难统一管理时,有人会用 getCurrentPages() 拿上一页实例并调 setData 或改 $vm。这方法见效快,但耦合极强,且在热更新、H5 多标签页、某些小程序平台下容易出错。
- 务必判空:
const prevPage = pages[pages.length - 2]可能为undefined(如首页直接进详情页) - 不要直接赋值
prevPage.$vm.xxx = yyy,优先走prevPage.setData({ xxx: yyy }),兼容性更好 - 修改后不要期望页面立刻响应:Vue 响应式依赖
setData触发,直接改$vm在部分平台(尤其 H5)可能无效 - 如果项目用了 Pinia/Vuex,这类操作应降级为 dispatch action,而非绕过状态管理直接改页面 data
最易被忽略的一点:不同平台对 onShow 的触发时机有细微差异,iOS 小程序和 Android 小程序在页面缓存策略上并不完全一致,H5 更依赖浏览器可见性 API。不要假设“写了 onShow 就一定准时执行”,关键数据同步逻辑最好搭配服务端时间戳或版本号做二次校验。











