小程序生命周期详解:onLoad 与 onShow 数据加载时机

12 ℃ 0 条
内容摘要小程序生命周期里最容易踩的坑,是页面数据该在何时加载。本文梳理应用级与页面级生命周期函数的执行顺序,说明 onLoad、onShow、onReady 的触发条件与取参差异,给出按数据是否变化选择加载位置的方法,并处理请求竞态与页面栈十层上限等问题。
小程序生命周期详解:onLoad 与 onShow 数据加载时机

小程序的页面数据加载不像浏览器页面只走一次:同一个页面被反复打开时 onLoad 只执行一次,onShow 却每次显示都触发。请求写 onLoad 里,改完数据返回页面还是旧值;写 onShow 里又容易出现重复请求和竞态。

小程序生命周期与数据加载时机

一、生命周期函数的执行顺序

1. 应用级与页面级生命周期

小程序分 App 与 Page 两层。应用级 onLaunch 冷启动执行一次,切后台触发 onHide,切回前台触发 onShow。页面级顺序固定为 onLoad → onShow → onReady,页面隐藏触发 onHide,出栈销毁触发 onUnload。

onLoad 接收 options 参数,即路由传参。例如 navigateTo 的 url 写成 /pages/detail/detail?id=8,在 onLoad(options) 里用 options.id 取到。这是唯一能拿到原始路由参数的时机,onShow 不带参数。

2. onLoad、onShow、onReady 的区别

onLoad 对同一个页面实例只调用一次,适合初始化。onShow 每次页面显示都调用,含首次进入、从子页面返回、从后台切回。onReady 在首次渲染完成后调用一次,此时可用 createSelectorQuery 查询节点尺寸。三者首次进入按 onLoad → onShow → onReady 执行,异步请求不会阻塞 onShow 触发。

二、数据加载时机怎么选

1. 只加载一次的数据放 onLoad

不随页面切换变化的静态数据,如字典表、分类列表、配置项,放 onLoad 里只请求一次。放 onShow 则每次返回都重新拉取,浪费带宽又拖慢页面。

2. 需要刷新的数据放 onShow 并去重

订单列表、未读消息数这类会被其他页面修改的数据,必须放 onShow。但首次进入时 onLoad 已执行过,两处都写请求会重复。常见做法是 onLoad 只解析参数,请求统一放 onShow:```js
Page({ onLoad(o) { this.id = o.id; },
onShow() { this.fetchList(); } });


若只在首次加载、返回时不刷新,用标记位控制:

```js
onShow() { if (!this.loaded) { this.loaded = true; this.fetchList(); } }

三、常见坑与实现细节

1. 返回页面不刷新

用 navigateTo 打开详情页做修改,返回列表页会触发其 onShow,刷新逻辑放这里就生效。但 switchTab 只触发 onShow,不重新执行 onLoad;redirectTo 会关闭当前页,返回时触发新页面的 onLoad。选错跳转方式,刷新就失效。

2. 重复请求与竞态

网络慢时 onShow 可能连续触发,上次请求未返回新的又发出,后到的旧数据会覆盖新数据。办法是请求前记录序号,只采纳最新结果:```js
const seq = (this.seq = (this.seq || 0) + 1);
wx.request({ url: '/api/list', success: r => {
if (seq === this.seq) this.setData({ list: r.data }); } });


### 3. 页面栈层数限制

页面栈最多十层,超过后 `navigateTo` 失败。从列表进详情再进二级详情,反复操作容易溢出,此时改用 `redirectTo` 替换当前页,或把详情做成组件。

## 关键配置提示

- `onLoad` 取路由参数,`onShow` 不带参数
- 需要刷新的请求统一放 `onShow`,仅首次加载用 `loaded` 标记拦住
- 页面栈上限十层,深层跳转用 `redirectTo`

发表评论 (已有0条评论)

快来评论,快来抢沙发吧~