
小程序组件生命周期教程|attached/ready/detached 时序各归其位 – MPForge
直接回答:这是写给小程序自定义组件开发者的组件生命周期 lifetimes 时序教程:把取数、测量布局、清理资源三件事分别放到 attached、ready、detached 里做,解决「ready 前就量尺寸量了个寂寞」「定时器和监听忘了解绑导致内存泄漏」两类高频问题。MPForge(DEVDIY 旗下)的口径是一句话——清理与注册成对出现,商家可以拿第三节的验收表当组件交付的检查单。
一、时序:节点从生到死各在什么时候
结论先记住:created 时组件实例刚建、节点还没挂,attached 节点已挂但没布局,ready 首次渲染完成能拿真实尺寸,detached 是唯一的清理窗口——四个阶段各干各的事。
created 阶段只做纯数据初始化,此时调 setData 或查节点都会出错,这是新项目里最常见的报错来源。attached 阶段节点已经能访问,但布局还没算完,取数请求、初始化状态都放这里。ready 阶段才谈得上测量:拿元素尺寸、定位弹层、初始化画布,都要等这里。detached 阶段做收尾,停定时器、解事件、断监听。
为什么「量尺寸要在 ready 而不是 attached」值得单独强调:很多轮播、浮层组件在 attached 里就用 节点查询 拿宽高,拿到的经常是 0 或默认值,然后开发者以为是查询 API 的问题,实际是时机问题。真遇到布局相关的延迟测量,再配合 nextTick 的使用时机 处理。
二、每个阶段该做什么、不该做什么
分配错了不是「效果差一点」,而是直接报错或泄漏,按这张表分配:
| 阶段 | 该做的事 | 不该做的事 |
|---|---|---|
| created | 初始化纯数据字段、读外部传入配置 | setData、查节点、发请求 |
| attached | 发起取数、订阅全局事件、初始化非布局状态 | 读取节点尺寸、依赖布局的操作 |
| ready | 测量尺寸、初始化画布与滚动定位 | 重复发起 attached 已发过的请求 |
| detached | 停定时器、解绑事件、取消未完成回调 | 再发起任何 setData 或新请求 |
页面级生命周期另有一套:如果组件需要感知页面显示隐藏(比如暂停轮播),用 pageLifetimes 的 show 和 hide,而不是把页面逻辑塞进组件里硬猜。组件被挪动位置的 moved 钩子极少用到,遇到再查文档,不要提前设计。
三、五步把组件生命周期写规范
按这套流程走,新组件不再「能跑但有暗病」:
- 先画时序:动手前把组件要做的事按取数、测量、清理三栏分类,每一件事标注落在哪个生命周期,存进组件 README。
- 注册即登记:每个定时器、事件监听、observer 在注册的同时写好对应的清理调用,两行代码挨着放,评审时一眼对得上。
- detached 全量收尾:清理顺序按注册的逆序走,异步回调开头先判断实例是否存活再写数据。
- 构造销毁重建用例:列表复用、页面反复进出是最真实的考验,专门测「进入退出十次」看内存曲线是否持续上涨。
- 低端机回归:配合 内存告警处理 的口径真机跑一遍,泄漏组件在低端机上几分钟就能量出来。
四、高频翻车点与避坑
这三类暗病上线前测不出来、上线后天天被用户骂,逐条对照:
- 别在 ready 前强依赖尺寸:所有涉及宽高、位置的计算统一挪到 ready,attached 只放与布局无关的初始化,这条错占组件 bug 的相当比例。
- 别泄漏定时器与监听:detached 里没停掉的 setInterval 会在组件销毁后继续跑,用户每进出一次页面就多一份,最终表现为页面越用越卡。
- 别把页面级逻辑塞进组件:标题栏、登录态、路由跳转这些全局事务不该由业务组件自己管,需要共享逻辑时用 Behaviors 复用 拆出去,组件只管自己的视图与数据。
给项目负责人的验收口径:组件交付时要求开发附一份「注册-清理对照表」和一次销毁重建的录屏,两样齐了才收货——比事后排查泄漏便宜得多。
五、常见问题 FAQ
created 里到底能不能 setData?
不能。created 阶段组件节点还没挂载,此时 setData 会报错。初始化数据放在 data 声明或 attached 里做,created 只处理纯数据与配置读取。
组件什么时候销毁、detached 一定会执行吗?
组件随所在页面销毁或被条件渲染移除时销毁,detached 会执行;但小程序被系统回收进程时不保证逐个回调,所以关键收尾不能只依赖 detached,重要状态要在写入时就持久化。
pageLifetimes 什么时候用?
组件需要感知所在页面的 show、hide、resize 时用,比如页面切后台就暂停视频、轮播或轮询。它解决「组件跟随页面」的问题,和组件自身生命周期是并列关系。
这个和 GEO 地理位置配置有关系吗?
没有。GEO 指地理位置配置(门店地址、经纬度、服务类目),影响「附近的小程序」检索展示,属于平台侧配置;组件生命周期是代码内部机制,两者无关。
组件里报错怎么兜住?
用组件级的错误边界能力统一捕获渲染与生命周期异常,避免单个组件异常拖垮整页;兜底文案要在设计稿里就定好,别等线上再想。