页面和自定义组件生命周期
页面和自定义组件的关系
自定义组件:
注意
@Component 装饰的 UI 单元 可以组合多个系统组件实现 UI 的复用
可以调用组件的生命周期
页面
注意
页面可以由一个或者多个自定义组件构成
@Entry 装饰的自定义组件为页面的入口组件,即页面的根节点,一个页面有且仅能有一个@Entry。
只有被@Entry 装饰的组件才可以调用页面的生命周期。
生命周期
流程图
下图展示的是被@Entry
装饰的组件(页面)生命周期
组件生命周期(页面也执行)
注意
即一般用@Component
装饰的自定义组件的生命周期
aboutToAppear
--首选获取数据之类的
组件即将出现时执行该方法 具体时机为在创建自定义组件的新实例后,在执行其 build()函数之前执行。
onDidBuild
-- 不建议使用
组件 build()函数执行完成之后回调该接口,开发者可以在这个阶段进行埋点数据上报等不影响实际 UI 的功能。
不建议在 onDidBuild 函数中更改状态变量、使用 animateTo 等功能,这可能会导致不稳定的 UI 表现
aboutToDisappear
在自定义组件析构销毁之前执行。 不建议在这里面使用异步函数否则会造成内存溢出
不允许在aboutToDisappear
函数中改变状态变量,
特别是@Link
变量的修改可能会导致应用程序行为不稳定
页面生命周期
onPageShow
页面每次显示的时候触发一次,包括路由过程,应用进入前台等场景
onPageHide
页面每次隐藏的时候触发一次,包括路由过程,应用进入后台等场景
onBackPress
当用户点击返回按钮的时候触发
自定义组件和页面生命周期的关联
简单来说:
先执行页面级别的
aboutToAppear
与onDidBuild
,然后执行组件级别的生命周期aboutToAppear
与onDidBuild
然后在页面级别的
onPageShow
与onPageHide
中执行组件级别的onPageShow
与onPageHide
bash
// Index.ets
import { router } from '@kit.ArkUI';
@Entry
@Component
struct MyComponent {
@State showChild: boolean = true;
@State btnColor:string = "#FF007DFF";
// 只有被@Entry装饰的组件才可以调用页面的生命周期
onPageShow() {
console.info('Index onPageShow');
}
// 只有被@Entry装饰的组件才可以调用页面的生命周期
onPageHide() {
console.info('Index onPageHide');
}
// 只有被@Entry装饰的组件才可以调用页面的生命周期
onBackPress() {
console.info('Index onBackPress');
this.btnColor ="#FFEE0606";
return true // 返回true表示页面自己处理返回逻辑,不进行页面路由;返回false表示使用默认的路由返回逻辑,不设置返回值按照false处理
}
// 组件生命周期
aboutToAppear() {
console.info('MyComponent aboutToAppear');
}
// 组件生命周期
onDidBuild() {
console.info('MyComponent onDidBuild');
}
// 组件生命周期
aboutToDisappear() {
console.info('MyComponent aboutToDisappear');
}
build() {
Column() {
// this.showChild为true,创建Child子组件,执行Child aboutToAppear
if (this.showChild) {
Child()
}
// this.showChild为false,删除Child子组件,执行Child aboutToDisappear
Button('delete Child')
.margin(20)
.backgroundColor(this.btnColor)
.onClick(() => {
this.showChild = false;
})
// push到page页面,执行onPageHide
Button('push to next page')
.onClick(() => {
router.pushUrl({ url: 'pages/page' });
})
}
}
}
@Component
struct Child {
@State title: string = 'Hello World';
// 组件生命周期
aboutToDisappear() {
console.info('[lifeCycle] Child aboutToDisappear')
}
// 组件生命周期
onDidBuild() {
console.info('[lifeCycle] Child onDidBuild');
}
// 组件生命周期
aboutToAppear() {
console.info('[lifeCycle] Child aboutToAppear')
}
build() {
Text(this.title)
.fontSize(50)
.margin(20)
.onClick(() => {
this.title = 'Hello ArkUI';
})
}
}
自定义组件监听页面生命周期
- 通过 UIObserver 来监听
bash
// Index.ets
import { uiObserver, router, UIObserver } from '@kit.ArkUI';
@Entry
@Component
struct Index {
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(`Index onPageShow`);
} else if (info.state == uiObserver.RouterPageState.ON_PAGE_HIDE) {
console.log(`Index 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(`this page is ${this.queryRouterPageInfo()?.pageId}`)
.fontSize(25)
Button("push self")
.onClick(() => {
router.pushUrl({
url: 'pages/Index'
})
})
Column() {
SubComponent()
}
}
}
}
@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`)
}
}
}