文档目录
页面生命周期管理

简介

本技术文档围绕 DouPHP 小程序的“页面生命周期管理”展开,系统阐述页面从创建到销毁的完整生命周期(onLoad、onShow、onReady、onHide、onUnload),并结合仓库中的实际代码,说明:

  • 页面初始化流程与数据加载策略
  • 资源清理机制与内存泄漏防护
  • 页面级状态、组件状态与全局状态的协调管理
  • 最佳实践与性能优化建议
  • 错误处理策略与常见问题定位

项目结构

DouPHP 的小程序实现位于 miniprogram 目录下,包含 default 与 company 两套主题/业务模板。每个模板均提供:

  • 应用入口 app.ts:负责全局初始化、错误捕获、自动更新、推广参数解析等
  • 状态管理 stores:基于 MobX 的全局状态聚合与引导
  • 页面 pages:以功能模块划分,每个页面拥有独立的 TypeScript 逻辑文件
  • 类型定义 libs/miniprogram-api-typings:提供微信小程序 API 的类型声明,包括页面生命周期接口
graph TB
subgraph "小程序应用"
A["应用入口<br/>app.ts"]
B["状态引导<br/>stores/index.ts"]
C["认证状态<br/>stores/auth.ts"]
end
subgraph "首页示例"
D["页面逻辑<br/>pages/index/index.ts"]
end
A --> B
B --> C
A --> D
B --> D

核心组件

  • 应用入口(App)
    • onLaunch:注册 HTTP 错误拦截器、解析推广参数、引导全局 store、计算导航栏高度、启动自动更新、调试模式开关
    • onShow:再次尝试解析推广参数(适用于后台切回或卡片冷启)
    • onError/onUnhandledRejection/onPageNotFound:全局异常与路由缺失的统一处理
  • 状态引导(bootstrapStores)
    • 先 hydrate(从 storage 恢复本地状态,实现秒开)
    • 再 refresh/restore(网络刷新;失败保留本地缓存)
    • 绑定购物车角标(统一由 cartStore.badge 驱动)
  • 认证状态(authStore)
    • hydrate:从 storage 恢复登录态
    • restore:拉取用户信息并设置 is_login/is_vip/is_work/is_distribution
    • ensureLogin:未登录时跳转登录页
    • login/logout:持久化凭证与状态重置
  • 页面示例(首页 index)
    • onLoad:设置标题、显示分享菜单、绑定 store、请求首页数据、加载商品列表
    • onShow:刷新购物车状态
    • onReady:恢复认证态后根据工作态跳转
    • onUnload:解绑 store 绑定,释放资源

架构总览

下图展示了小程序应用启动到页面渲染的关键调用链与数据流:

sequenceDiagram
participant WX as "微信宿主"
participant App as "应用入口(app.ts)"
participant Store as "状态引导(stores/index.ts)"
participant Auth as "认证状态(stores/auth.ts)"
participant Page as "页面(index.ts)"
WX->>App : 触发 onLaunch(options)
App->>App : 注册HTTP错误拦截器
App->>App : 解析推广参数(user_sn)
App->>Store : bootstrapStores()
Store->>Auth : hydrate() / restore()
Store-->>App : 完成状态预热
App->>WX : 计算导航栏高度/启动自动更新
WX->>Page : 页面 onLoad(query)
Page->>Store : 绑定 store 字段
Page->>Page : 发起网络请求(首页数据/商品列表)
WX->>Page : 页面 onReady()
Page->>Auth : restore() -> 可能跳转工作页
WX->>Page : 页面 onShow()
Page->>Store : 刷新购物车状态
WX->>Page : 页面 onHide()/onUnload()
Page->>Page : 解绑 store 绑定/清理资源

详细组件分析

页面生命周期钩子与执行时机

  • onLoad(query)
    • 页面加载时触发一次,适合读取路由参数、初始化数据、发起首屏请求
    • 在首页中用于设置标题、绑定 store、请求首页数据与商品列表
  • onShow()
    • 页面显示/切入前台时触发,适合刷新需要实时性的数据(如购物车数量)
  • onReady()
    • 页面初次渲染完成,适合进行视图交互与 DOM 查询(如滚动条宽度测量)
    • 在首页中用于恢复认证态并根据工作态跳转
  • onHide()
    • 页面隐藏/切入后台时触发,适合暂停定时器、取消监听
  • onUnload()
    • 页面卸载时触发,适合释放资源(如解绑 store 绑定、清理事件监听)

页面初始化流程与数据加载策略

  • 应用层
    • onLaunch:注册 HTTP 错误拦截器、解析推广参数、引导全局 store、计算导航栏高度、启动自动更新、开启调试模式
  • 状态层
    • bootstrapStores:先 hydrate(storage 秒开),再 refresh/restore(网络刷新),最后绑定购物车角标
  • 页面层
    • onLoad:绑定 store 字段、请求首页数据、加载商品列表
    • onReady:恢复认证态,必要时跳转工作页
    • onShow:刷新购物车状态
flowchart TD
Start(["应用启动"]) --> Launch["App.onLaunch"]
Launch --> Bootstrap["bootstrapStores()"]
Bootstrap --> Hydrate["hydrate() 从 storage 恢复"]
Hydrate --> Refresh["refresh()/restore() 网络刷新"]
Refresh --> BindBadge["绑定购物车角标"]
BindBadge --> PageLoad["页面 onLoad()"]
PageLoad --> FetchData["请求首页数据/商品列表"]
FetchData --> Ready["页面 onReady()"]
Ready --> AuthRestore["恢复认证态/可能跳转"]
AuthRestore --> Show["页面 onShow()"]
Show --> End(["页面就绪并可交互"])

资源清理机制与内存泄漏防护

  • 页面卸载时解绑 store 绑定,避免引用残留导致内存泄漏
  • 使用 wx.nextTick 与 SelectorQuery 获取节点尺寸后,仅保存必要计算值,避免持有大对象
  • 对网络请求的错误分支进行兜底,确保 UI 状态可恢复(如 loadpage 置为 false)

页面状态管理(页面级、组件级、全局状态)

  • 全局状态(stores)
    • commonStore:站点信息、语言、特性开关、导航列表等
    • authStore:登录态、VIP/工作/分销标志
    • cartStore:购物车数据与角标
  • 页面级状态(Page.data)
    • 首页维护分类指示器、商品列表、分页、加载状态等
  • 组件级状态(未在本文直接展示)
    • 通过组件 lifetimes 与 data 管理局部状态
classDiagram
class CommonStore {
+site
+lang
+data
+param
+features
+nav_list
+hydrate()
+refresh()
}
class AuthStore {
+api_token
+user_id
+loginEd
+is_login
+is_vip
+is_work
+is_distribution
+hydrate()
+restore()
+ensureLogin()
+login()
+logout()
}
class CartStore {
+badge
+refresh()
}
class IndexPage {
+navigationBarAndStatusBarHeight
+index
+product_list
+page
+nomore
+loadpage
+onLoad()
+onShow()
+onReady()
+onUnload()
}
IndexPage --> CommonStore : "绑定字段"
IndexPage --> AuthStore : "恢复认证态"
IndexPage --> CartStore : "刷新购物车"

典型场景的生命周期使用方法

  • 首次进入首页
    • onLoad:设置标题、绑定 store、请求首页数据与商品列表
    • onReady:恢复认证态,若处于工作状态则跳转到工作页
  • 切换到前台
    • onShow:刷新购物车状态,保证角标与数量一致
  • 离开页面
    • onUnload:解绑 store 绑定,释放资源

依赖关系分析

  • 应用入口依赖状态引导与 HTTP 服务
  • 状态引导依赖各 store(common/auth/cart)
  • 页面依赖 store 与 HTTP 服务,并在生命周期中触发数据刷新与状态同步
graph LR
App["应用入口(app.ts)"] --> Stores["状态引导(stores/index.ts)"]
Stores --> Auth["认证状态(stores/auth.ts)"]
App --> Page["页面(index.ts)"]
Stores --> Page
Page --> HTTP["HTTP服务"]

性能考量

  • 首屏秒开:通过 hydrate 从 storage 恢复状态,减少白屏时间
  • 网络刷新:在 hydrate 之后再进行 refresh/restore,失败不影响本地展示
  • 角标统一驱动:cartStore.badge 通过 autorun 绑定,避免多处重复 setTabBarBadge
  • 延迟加载与分页:商品列表采用分页与触底追加,降低首屏数据量
  • 调试模式:非正式版开启 vConsole,便于快速定位问题

故障排查指南

  • 全局错误捕获
    • App.onError:记录错误日志,调试期弹出 modal
    • App.onUnhandledRejection:记录未处理的 Promise 拒绝
    • App.onPageNotFound:记录路由不存在的路径,调试期提示
  • 认证态异常
    • UNAUTHORIZED:统一登出并清空登录态
    • 其他错误(NETWORK_ERROR/HTTP_5xx/NOT_FOUND):保留当前登录态,避免弱网导致的假登出
  • 页面级错误
    • 网络请求失败:显示错误消息,确保 UI 状态可恢复(如 loadpage 置为 false)

结论

DouPHP 小程序通过应用入口、状态引导与页面生命周期的协同,实现了高效、稳定的页面生命周期管理:

  • 应用层负责全局初始化与错误处理
  • 状态层通过 hydrate/refresh/restore 保障首屏体验与数据一致性
  • 页面层在合适的生命周期钩子中进行数据加载、状态刷新与资源清理 结合分页加载、统一角标驱动与调试模式,整体具备良好的性能与可维护性。

附录

  • 页面生命周期接口参考
    • ILifetime:onLoad、onShow、onReady、onHide、onUnload、onRouteDone、onPullDownRefresh、onReachBottom 等
  • 推荐实践清单
    • 在 onLoad 中初始化数据与绑定 store
    • 在 onShow 中刷新需要实时性的数据
    • 在 onReady 中进行视图交互与 DOM 查询
    • 在 onHide 中暂停定时器与取消监听
    • 在 onUnload 中解绑 store 与释放资源
    • 使用 hydrate/refresh/restore 保障首屏与数据一致性
    • 统一错误处理与调试模式
添加日期:2026-10-05