页面和自定义组件生命周期
组件和页面的关系
- 自定义组件:@Component装饰的UI单元,可以组合多个系统组件实现UI的复用,可以调用组件的生命周期。
- 页面:应用的UI页面,可以由一个或者多个自定义组件组成。@Entry装饰的自定义组件可以作为页面的入口组件,一个页面只能有一个@Entry。只有被@Entry装饰的自定义组件,才可以调用页面的生命周期。
生命周期
页面生命周期
- onPageShow:页面每次显示的时候触发一次,包括路由过程、应用进入前台等场景。
- onPageHide:页面每次隐藏的时候触发一次,包括路由过程、应用进入后台等场景。
- onBackPress:当用户点击返回按钮的时候触发。
组件生命周期
- aboutToAppear:组件即将出现时回调该接口,具体时机为创建自定义组件的新实例后,其build()函数执行之前。
- onDidBuild:组件build()函数执行完成之后回调该接口,不建议在onDidBuild函数中更改状态变量、使用animateTo等功能,可能会导致UI表现不稳定。
- aboutToDisappear:在组件销毁之前执行,不允许在aboutToDisappear中改变状态变量。
@Entry装饰的组件,即页面的生命周期流程如下图:
普通流程为:
aboutToAppear --> build --> onDidBuild --> onPageShow --> onPageHide --> aboutToDisappear
页面即将出现–>执行组件build函数–>build完成–>页面显示–>页面隐藏–>组件销毁,即将消失
其他流程:
-
如果页面有@Entry A,@Component B,B的子组件C,那么生命周期流程为:
A aboutToAppear --> A build --> A onDidBuild -> B aboutToAppear -> B build -> B onDidBuild -> C aboutToAppear -> C build -> C onDidBuild -> A onPageShow -
如果要删除B节点,那么后续生命周期流程为:
B aboutToDisappear -> C aboutToDisappear -
跳转其他页面:
router.pushUrl: A onPageHide -> 新页面的初始化生命周期
router.replaceUrl: A onPageHide -> A aboutToDisappear -> B aboutToDisappear -> C aboutToDisappear -> 新页面的初始化生命周期 -
点击返回按钮:A onBackPress -> A onPageHide -> A aboutToDisappear -> B aboutToDisappear -> C aboutToDisappear
-
最小化应用或者应用进入后台:A onPageHide
-
应用回到前台: A onPageShow
-
退出应用:A onPageHide -> A aboutToDisappear -> B aboutToDisappear -> C aboutToDisappear
自定义组件的创建和渲染流程
首次创建
- 实例创建:自定义组件的实例由ArkUI框架创建。
- 初始化成员变量:通过组件内部默认值或者构造方法传入参数来初始化自定义组件的成员变量,初始化顺序为成员变量的定义顺序。
- 如果定义了aboutToAppear函数,则执行aboutToAppear函数。
- 首次渲染时,执行build函数,如果子组件为自定义组件,则创建子组件的实例。在首次渲染的过程中,框架会记录状态变量和组件之间的映射关系,后续当状态变量发生变化时,驱动其相关的组件刷新。
- 如果定义了onDidBuild函数,则执行onDidBuild函数。
- 如果有子组件,那么会执行子组件的上述步骤。
重新渲染
当事件句柄被触发,状态变量发生变化,或者LocalStorage/AppStorage中的属性发生更改,导致绑定的状态变量发生变化时,ArkUI框架观察到了状态变量的变化,会根据初次渲染时,框架内部记录的组件与状态变量之间的关系,以及对应组件的更新函数。执行这些更新函数,实现最小化更新。
自定义组件的删除
如果if组件的分支改变,或者FroEach循环渲染中数组的个数改变,组件将被删除。
- 组件删除之前,将调用其aboutToDisappear生命周期函数,表示该节点将要被销毁。
- 自定义组件和他的变量将被删除,如果有同步的变量,如@Link、@Prop、@StorageLink,将从同步源上取消注册。
AekUI的节点删除机制如下:
- 后端节点直接从组件树上摘下,后端节点被销毁。
- 前端节点解引用,前端节点已经没有引用时,将被JS虚拟机垃圾回收。
不建议在生命周期aboutToDisappear中使用async await,如果在生命周期aboutToDisappear中使用异步操作,自定义组件将被保留在闭包中,直到回调方法被执行完成,这种行为阻止了自定义组件的垃圾回收。
自定义组件监听页面生命周期
使用无感监听页面路由的能力,能够实现在自定义组件中监听页面的生命周期。
@Component
struct SubComponent {
listener: (info: uiObserver.RouterPageInfo) => void = (info: uiObserver.RouterPageInfo) => {
let routerInfo: uiObserver.RouterPageInfo | undefined = this.queryRouterPageInfo();
if (info.pageId == routerInfo?.pageId) {
if (info.state == uiObserver.RouterPageState.ON_PAGE_SHOW) {
console.log(`SubComponent onPageShow`);
} else if (info.state == uiObserver.RouterPageState.ON_PAGE_HIDE) {
console.log(`SubComponent onPageHide`);
}
}
}
aboutToAppear(): void {
let uiObserver: UIObserver = this.getUIContext().getUIObserver();
uiObserver.on('routerPageUpdate', this.listener);
}
aboutToDisappear(): void {
let uiObserver: UIObserver = this.getUIContext().getUIObserver();
uiObserver.off('routerPageUpdate', this.listener);
}
build() {
Column() {
Text(`SubComponent`)
}
}
}
标签:ArkTs,生命周期,自定义,UI,build,组件,aboutToDisappear,页面
From: https://blog.csdn.net/gitzzp/article/details/141256658