ArkUI 自定义组件生命周期自学指南
做 ArkUI / ArkTS 的时候,很多问题表面看起来像是: 其实大多数都和一个东西有关:生命周期放错地方了。 这篇就不写太“官方文档翻译”的风格,直接按平时开发会遇到的场景来讲,尽量让你看完就知道“这段逻辑该放哪”。 ArkUI 里常用生命周期可以分成几类: 另外还有个不是生命周期、但必须有的: 它的职责很简单:组件长什么样。 所以平时常见误区是: 这些都不太合适。 这三个是日常写组件最常用的。 这个阶段很好理解:组件要出现了。 它的特点是: 因为很多场景下组件会频繁创建销毁(比如列表项、条件渲染), 这个回调很适合做一类事:不影响当前 UI 的逻辑。 比如: 简单说就是: 这个阶段就一个核心原则: 尤其是不要在这里改 这个一定要分清,不然会经常写错地方。 触发场景包括: 触发场景包括: 这里也建议别做重的同步操作,不然切页面的时候会卡。 这个在做“二次确认退出”“先关弹窗再返回”时特别常用。 返回规则很简单: 页面上有弹层时,优先关闭弹层,不直接退出页面。 这个不是每次路由都会触发,它只在一个场景下出现: 这时候不会重新创建页面,而是触发 这个回调对做路由优化很有用,不然很多人会以为“怎么没重新走 aboutToAppear”。 如果你在做列表、瀑布流、滑动卡片,这组生命周期很重要。 当组件被标记为可复用(比如 一句话: 组件从组件树上移除、准备进复用缓存前会触发。 这个回调写得好不好,直接关系到列表长时间滑动后的内存表现。 在 本质没变,还是那句话:复用回调追求快。 这个回调很多人没用过,但其实很实用,尤其是做深浅色 / 品牌色适配的时候。 它的触发时机是: 而且这里允许改状态变量,改完后 如果你项目后面会做统一主题,这个回调会非常顺手。 这个生命周期是做页面进入/离开动画的。 如果你有页面切换动画需求,建议在这里统一处理,而不是把动画逻辑散在按钮点击事件里。后期维护会轻松很多。 如果你有卡片(Form)场景,这两个回调要知道。 卡片被回收时触发,可以返回一个字符串,交给卡片管理服务代保存。 你可以理解成: 卡片恢复时触发,会拿到之前保存的那段字符串。 你可以理解成: 适合保存的是轻量状态,比如: 不建议塞太大的内容。 官方说明里允许在生命周期函数中使用 Promise / 异步回调(比如网络请求、定时器等),这个在实际开发里非常常见。 但“能写”不代表“哪里都适合写”。 表现通常是: 解决思路: 尤其是频繁创建销毁的组件,直接导致: 解决思路: 比如: 结果当然是行为不符合预期。 记住: 你在列表里滑动时, 解决思路: 如果你是刚开始接触,不用一口气全背,按这个顺序就行: 很多“看起来像玄学”的问题,其实不是框架抽风,而是生命周期职责混了: 把生命周期当成不同工位来用,代码会明显顺很多,后面排查问题也快很多。先说结论:生命周期不是背下来,而是知道“谁负责什么”
1)组件创建 / 销毁相关
aboutToAppearonDidBuild(API 12+)aboutToDisappear2)页面(@Entry)相关
onPageShowonPageHideonBackPressonNewParam(API 19+,单实例路由常用)3)复用组件(性能优化重点)
aboutToReuseaboutToRecycle4)主题相关
onWillApplyTheme(API 12+)5)卡片相关
onFormRecycleonFormRecoverbuild():定义 UI 的地方一、build():这个不是“做逻辑”的地方,是“描述 UI”的地方
build() 是每个自定义组件都要写的。
状态变了以后,框架会重新根据 build() 去更新 UI。build() 里写初始化逻辑build() 里做重计算build() 里发请求build() 尽量保持“干净”,让它只负责 UI 描述。二、组件生命周期(最常用):aboutToAppear / onDidBuild / aboutToDisappear
1)aboutToAppear:组件实例创建后、build 前触发
build() 前触发build() 可以直接用到适合放什么
不建议放什么
aboutToAppear 会被反复调用。这里一旦写重了,卡顿会非常明显。2)onDidBuild(API 12+):build 执行后触发
如果这段逻辑不需要参与这次 UI 渲染,那放 onDidBuild 会更顺手。3)aboutToDisappear:组件销毁时触发
只清理,不改状态。
@Link,容易导致不稳定行为。适合放什么
不要做什么
三、页面生命周期(只对 @Entry 页面生效)
onPageShow / onPageHide / onBackPress / onNewParam 这些是页面级生命周期,只对 @Entry 装饰的路由页面有效,不是普通组件都有。1)onPageShow:页面显示时触发
适合放什么
2)onPageHide:页面隐藏时触发
适合放什么
3)onBackPress:拦截返回键(页面级)
true:你自己处理,不走默认返回false:走默认返回逻辑false一个常见用法
4)onNewParam(API 19+):单实例页面收到新参数
onNewParam(param)。适合做什么
四、复用组件生命周期(列表优化重点)
1)aboutToReuse:从复用池里拿出来重新用
@Reusable),它从复用缓存重新加入节点树时会触发这个回调。适合做什么
注意点(很关键)
@Link / @ObjectLink / @Prop 这类自动更新的变量,不要重复乱赋值
这里是“快速换内容”的地方,不是“做重活”的地方。2)aboutToRecycle:进入复用池前触发
适合做什么
3)状态管理 V2 的复用(API 18+)
@ComponentV2 + @ReusableV2 场景里也有 aboutToReuse(),思路一样:五、onWillApplyTheme(API 12+):主题适配很好用
build() 前Themebuild() 直接生效。适合场景
build() 里一堆 if/else六、pageTransition(API 9+):页面转场动画
七、卡片生命周期:onFormRecycle / onFormRecover(做 ArkTS 卡片时会用到)
1)onFormRecycle
“卡片被系统收走前,我先存一点状态。”2)onFormRecover
“卡片回来了,把上次状态拿回来恢复一下。”八、生命周期里能不能写异步?可以,但别乱放
比较稳的写法
aboutToAppear 里发起异步请求(轻量触发)aboutToDisappear / onPageHide 做清理(停定时器、解绑订阅等)不太稳的写法
aboutToReuse)里反复发请求九、实际开发里最容易踩的几个坑(真的很常见)
坑 1:在
aboutToDisappear 里改状态
销毁阶段只清理,不做 UI 状态更新。坑 2:
aboutToAppear 里塞太多东西
初始化可以做,但尽量轻量;重逻辑缓存化、异步化。坑 3:把页面逻辑写在普通组件里
onPageShow / onPageHideonBackPress@Entry 页面级的坑 4:复用回调里做重逻辑
aboutToReuse 会被频繁调用。
这里一旦做重活,帧率会掉得很明显。
复用回调只做必要更新,别做重计算、别做复杂阻塞操作。十、一个很好用的“职责分工”记法(推荐直接记)
组件级
页面级(@Entry)
复用组件
主题
卡片
十一、给新手的学习顺序(这样学最快)
第一阶段(先够用)
buildaboutToAppearaboutToDisappearonBackPress第二阶段(页面体验)
onPageShowonPageHide第三阶段(性能优化)
aboutToReuseaboutToRecycle第四阶段(进阶)
onWillApplyThemeonDidBuildonNewParam第五阶段(特定场景)
onFormRecycleonFormRecoverpageTransition最后一句(也是这篇的核心)