一、引言
在鸿蒙Next应用开发中,理解页面和自定义组件的生命周期至关重要。它有助于开发者精确控制组件和页面在不同阶段的行为,优化应用性能,提升用户体验。本文将深入探讨鸿蒙Next中页面和自定义组件的生命周期,包括创建、渲染、重新渲染、删除以及监听页面生命周期等方面的内容。
二、自定义组件和页面的关系
自定义组件
- 由
@Component
装饰的UI单元,可组合多个系统组件实现UI复用,并能调用组件的生命周期。
- 由
页面
- 应用的UI页面,可由一个或多个自定义组件组成。其中,
@Entry
装饰的自定义组件是页面的入口组件(根节点),一个页面只能有一个@Entry
。只有被@Entry
装饰的组件才能调用页面的生命周期。
- 应用的UI页面,可由一个或多个自定义组件组成。其中,
三、生命周期接口
页面生命周期接口(被
@Entry
装饰的组件)onPageShow
:页面每次显示时触发,如路由过程、应用进入前台等场景。onPageHide
:页面每次隐藏时触发,如路由过程、应用进入后台等场景。onBackPress
:用户点击返回按钮时触发。
组件生命周期接口(一般
@Component
装饰的自定义组件)aboutToAppear
:组件即将出现时回调,在创建实例后、执行build()
函数前执行。onDidBuild
:组件build()
函数执行完成后回调,不建议在此函数中更改状态变量或使用某些功能(如animateTo
),以免导致UI表现不稳定。aboutToDisappear
:组件析构销毁前执行,不允许在此函数中改变状态变量(特别是@Link
变量修改可能导致应用不稳定)。
四、生命周期流程
(一)自定义组件的创建和渲染流程
实例创建
- 由ArkUI框架创建自定义组件实例。
成员变量初始化
- 通过本地默认值或构造方法传递参数初始化成员变量,顺序按定义顺序。
aboutToAppear执行(若定义)
- 若开发者定义了
aboutToAppear
方法,则执行该方法。
- 若开发者定义了
首次渲染
- 执行
build
方法渲染系统组件,若子组件为自定义组件,则创建其实例。首次渲染时框架记录状态变量与组件映射关系,以便状态变量改变时驱动相关组件刷新。
- 执行
onDidBuild执行(若定义)
- 若开发者定义了
onDidBuild
方法,则执行该方法。
- 若开发者定义了
(二)自定义组件重新渲染
当以下情况发生时触发重新渲染:
- 事件句柄触发(如点击事件)改变状态变量。
LocalStorage
/AppStorage
中的属性更改导致绑定的状态变量值改变。- 框架观察到变化后启动重新渲染,根据记录的映射关系找到相关UI组件及其更新函数,执行更新函数实现最小化更新。
(三)自定义组件的删除
触发条件
if
组件分支改变或ForEach
循环渲染中数组个数改变时,组件将被删除。
删除过程
- 调用
aboutToDisappear
生命周期函数标记节点将要销毁。ArkUI节点删除机制为后端节点从组件树摘下并销毁,对前端节点解引用,前端节点无引用时被JS虚拟机垃圾回收。 - 自定义组件及其变量被删除,同步变量(如
@Link
、@Prop
、@StorageLink
)从同步源取消注册。
- 调用
(四)注意事项
不建议在aboutToDisappear
生命周期内使用async await
,因为若使用异步操作,自定义组件将保留在Promise
闭包中,直到回调方法执行完,这会阻止组件的垃圾回收。
五、生命周期调用时机示例
(一)示例代码结构
Index.ets
- 包含
@Entry
装饰的MyComponent
(页面入口组件)和Child
(MyComponent
的子组件)。 MyComponent
中声明页面生命周期函数(onPageShow
、onPageHide
、onBackPress
)和组件生命周期函数(aboutToAppear
、onDidBuild
、aboutToDisappear
)。- 通过按钮操作控制
Child
组件的显示与隐藏、页面跳转等。
- 包含
page.ets
- 新页面的定义,包含页面生命周期函数(
onPageShow
、onPageHide
、onBackPress
)和组件初始化逻辑。
- 新页面的定义,包含页面生命周期函数(
(二)不同操作下的生命周期调用
应用冷启动
- 初始化流程:
MyComponent aboutToAppear
->MyComponent build
->MyComponent onDidBuild
->Child aboutToAppear
->Child build
->Child onDidBuild
->Index onPageShow
。
- 初始化流程:
点击“delete Child”按钮
if
绑定的this.showChild
变为false
,删除Child
组件,执行Child aboutToDisappear
方法。
点击“push to next page”按钮
- 调用
router.pushUrl
接口跳转到新页面,当前Index
页面隐藏,执行Index onPageHide
。新页面初始化流程执行。若调用router.replaceUrl
,Index
页面销毁,执行Index onPageHide
->MyComponent aboutToDisappear
->Child aboutToDisappear
后初始化新页面生命周期流程。
- 调用
点击返回按钮
- 触发
Index onBackPress
,且返回一个页面后Index
页面销毁。
- 触发
最小化应用或进入后台
- 触发
Index onPageHide
,Index
页面未销毁,不执行组件的aboutToDisappear
。应用回到前台时执行Index onPageShow
。
- 触发
退出应用
- 执行
Index onPageHide
->MyComponent aboutToDisappear
->Child aboutToDisappear
。
- 执行
六、自定义组件监听页面生命周期
通过使用无感监听页面路由的能力,在自定义组件中监听页面生命周期。
示例代码(以Index.ets为例)
- 导入相关模块(
uiObserver
、router
、UIObserver
)。 - 在
Index
组件中定义listener
函数,根据uiObserver.RouterPageInfo
判断页面状态并打印相应日志。 - 在
aboutToAppear
中注册监听,在aboutToDisappear
中取消监听。 SubComponent
组件中同样进行类似操作实现对页面生命周期的监听。
- 导入相关模块(
掌握鸿蒙Next页面和自定义组件的生命周期,开发者能够更精准地把握应用运行过程中的各个阶段,合理安排代码逻辑,优化应用性能,为用户提供更加稳定、高效的应用体验。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。