4.3 页面栈与生命周期协同


4.3 页面栈与生命周期协同

本节导读:跳转决定栈的形态,生命周期决定每页在栈上的"醒着与睡着"。本节用一次完整的进出栈序列把两页生命周期的事件顺序排清楚,讲 getCurrentPages 的正确用法与 onBackPress 的端差异,把"返回不刷新""返回被拦截失效"两个高频故障一次定位到底。

一次跳转的完整事件序列

商城的典型一幕:用户在首页点商品进详情,看完点返回。这条两秒的路径里,两页的生命周期按严格顺序接力。进详情时:首页 onHide(睡着但没销毁)→ 详情页 onLoad(拿到参数)→ onShow → onReady(首次渲染完成)。返回时:详情页 onUnload(销毁)→ 首页 onShow(醒来)。把序列画成时序图,后面所有"该在哪发请求"的争论都有了裁决依据:

这张图直接推导出三条工程纪律。首屏请求放 onLoad,与渲染并行抢时间;量节点的逻辑放 onReady,节点没渲染完量出来全是零;"返回要刷新"的逻辑放首页的 onShow——秒杀倒计时、购物车角标、会员积分都属于这类。反过来,把刷新逻辑错放 onLoad,就会出现"第二次进来数据是旧的"的经典故障,因为返回不触发 onLoad。

着重辨析:onShow 是双刃剑

onShow 解决返回刷新,也制造重复请求:首页 onShow 里写拉取全量列表,那么从详情页每返回一次就拉一次,网络与体验双输。工程上的折中是给刷新加时效:状态里记 lastFetchAt,onShow 里判断距上次拉取超过阈值(比如一分钟)才重新请求,否则只做轻量的角标同步。更精细的做法区分"回到页面"的来源——从详情返回做轻刷新,从支付结果 reLaunch 回来才做全量刷新,判断依据可以是 4.2 节跳转时带的来源参数。

getCurrentPages:读栈的正确姿势

页面栈对象可以通过 getCurrentPages() 读到,常见用途有两个:判断当前页位置(嵌套 H5 端调试时打日志)、在非页面模块里反查跳转上下文。用法上三句话要记牢:它返回的是栈快照,最后一项是栈顶当前页;只读,不要试图直接改栈里页面的数据来"曲线刷新",跨页改数请走事件或状态管理;不要在 App.vue 的 onLaunch 里调用,那时栈还没建立,拿到的是空数组。

// 判断当前是否栈底(栈底页隐藏返回按钮、隐藏"再逛逛"入口) const pages = getCurrentPages(); const isRoot = pages.length === 1; const route = pages[pages.length - 1].route; // 当前页路径,形如 pages/goods/detail

onBackPress:拦截返回的可用地图

"未保存提示"类需求靠 onBackPress。它的端覆盖是本节必须诚实交代的地图:App 端与 H5 端完整支持,返回函数里 return true 即拦截本次返回;微信小程序端不支持,返回键与左上角返回箭头都是宿主行为,框架拦不到。三端要一致的方案只有把交互改成框架内可控的动作:

export default { data() { return { formDirty: false, dialogShow: false }; }, onBackPress() { // #ifdef APP-PLUS || H5 if (this.formDirty) { this.dialogShow = true; return true; // 拦截本次返回,先弹确认 } // #endif // 非 App 与 H5 端不拦截 }, methods: { confirmLeave() { this.formDirty = false; uni.navigateBack(); } } };

小程序端的替代策略:表单页常驻自动草稿(每次修改落存储),返回丢的内容下次进来能恢复;或用小程序原生的"页面离开确认"式交互(将提示前置到修改时)。承认平台边界并设计绕行方案,好过假装拦截无处不在。

两个变式场景的生命周期推演

掌握了标准序列,再看两个变式。变式一,redirectTo 进结果页:被替换的表单页依次触发 onUnload,而不是 onHide——替换即销毁,所以表单页的未保存数据必须在跳转前自行落盘,指望 onHide 保存是靠不住的。变式二,TabBar 页首次切入:onLoad 同样只在第一次触发,之后每次切换 Tab 只走 onShow 与 onHide,因此 Tab 页的"每次可见都刷新"逻辑要放 onShow,且要配合时效判断,否则切换即全量拉取,四个 Tab 轮一圈就是四次重复请求。把标准序列记牢,变式只需记住两条差异:替换是销毁,切换常驻不销毁。

用日志验证你的生命周期认知

本节的知识点适合动手验证:给商城页面的 onLoad、onShow、onReady、onHide、onUnload 各挂一行带页面名的日志,然后把 4.2 的下单动线完整走一遍,对照日志输出与本节的序列推演是否一致。做过这次验证的团队有一个共同的反馈——推演与实际至少差一处,而差异点往往就是该项目真实的刷新故障根源。验证之后把日志序列截图贴进团队文档,新人接手时的生命周期答疑成本直接降为零。认知类知识,用一次实验巩固胜过十次复习。

本节要点回顾

  • 进出栈的生命周期序列是固定的:进页 onLoad、onShow、onReady,返回时栈顶 onUnload、下层 onShow;
  • 首屏请求放 onLoad、量节点放 onReady、返回刷新放 onShow,三条各就各位;
  • onShow 刷新要加时效阈值,区分返回来源,避免重复全量拉取;
  • getCurrentPages 只读快照,栈顶是最后一项,onLaunch 时期栈还没建立;
  • onBackPress 在 App 与 H5 可靠、微信端失效,跨端方案改成自动草稿或前置确认。

栈与生命周期协同完毕,下一节处理常驻骨架:TabBar 的配置边界与自定义导航栏的安全区功课。


作者与出处
原作者: 灏天文库
来源:灏天文库
整理: 灏天文库整理
由灏天文库平台收录,内容或由平台用户上传,仅供学习交流
发布者: 作者: 灏天文库 转发
评论区 (0)
U