自定义组件:是使用@Component 装饰的 UI 单元,可以使用多个系统组件来封装可以复用的组件。
页面:就是应用的 UI 页面,可以由一个或者多个自定义组件构成,页面则是使用@Entry 装饰的自定义组件作为页面的入口组件,也就是页面的根节点。一个页面只能有一个@Entry 装饰器,只有被@Entry 装饰的组件,才可以调用页面的生命周期。
页面的生命周期,有这几个:
- onPageShow:页面每次显示的时候触发一次。包括通过路由进入页面和应用进入前台等场景。
- onPageHide:页面隐藏的时候触发一次,包括路由切换和应用进入后台等场景。
- onBackPress:用户点击返回按钮的时候触发。
组件的生命周期函数:
- aboutToAppear:组件即将出现的时候调用,在构建自定义组件的实例以后,在 build 函数之前执行。
- onDidBuild:组件的 build 函数执行完成之后调用,不推荐在 onDidBuild 函数中更改状态变量、使用 animateTo 这些功能,否则会导致 UI 渲染不稳定。
- aboutToDisappear:在自定义组件析构销毁之前执行,不允许在 aboutToDisappear 函数内修改状态变量,尤其是@Link 变量的修改,可能会导致应用程序行为不稳定。
自定义组件的渲染流程:
- 自定义组件的实例由 ArkUI 框架创建
- 初始化自定义组件内的成员变量
- 如果组件组件内定义了 aboutToAppear,那么就执行它
- 在首次渲染的时候,执行 build 方法 渲染系统组件,如果子组件是自定义组件,那就先创建自定义组件的实例。首次渲染的时候,ArkUI 框架会记录状态变量和组件的映射关系,在状态变量发生改变的时候,就触发对应的组件刷新。
- 如果组件内定义了 onDidBuild,那么就会执行它。
组件被删除的时候:
- 在删除组件之前,将调用其aboutToDisappear生命周期函数,标记着该节点将要被销毁。ArkUI的节点删除机制是:后端节点直接从组件树上摘下,后端节点被销毁,对前端节点解引用,前端节点已经没有引用时,将被JS虚拟机垃圾回收。
- 自定义组件和它的变量将被删除,如果其有同步的变量,比如@Link、@Prop、@StorageLink,将从同步源上取消注册。
完整的代码如下:
import CommonConstants from "../common/constants/Contants";
import { TODO_DATA } from "../common/data/SouresData"
@Entry
@Component
struct ToDoList {
@State title: string = '';
onPageShow() {
console.info('Index onPageShow');
}
onPageHide() {
console.info('Index onPageHide');
}
onBackPress() {
console.info('Index onBackPress');
return true // 返回true表示页面自己处理返回逻辑,不进行页面路由;返回false表示使用默认的路由返回逻辑,不设置返回值按照false处理
}
aboutToAppear() {
console.info('MyComponent aboutToAppear');
}
onDidBuild() {
console.info('MyComponent onDidBuild');
}
aboutToDisappear() {
console.info('MyComponent aboutToDisappear');
}
build() {
Column() {
Text(CommonConstants.TODO_TITLE)
.id('ToDoListHelloWorld')
.fontSize(30)
.fontWeight(FontWeight.Bold)
.alignRules({
center: { anchor: '__container__', align: VerticalAlign.Center },
middle: { anchor: '__container__', align: HorizontalAlign.Center }
})
.margin({
bottom: 20
})
ForEach(TODO_DATA, (item: string) => {
ToDoItem({ contents: item })
}, (item: string) => item)
}
.margin({
left: 10,
top: 10
})
}
}
/**
* 自定义的 Item 组件
*/
@Preview
@Component
struct ToDoItem {
private contents?: string
build() {
Row() {
Image($r("app.media.startIcon"))
.width(50)
.height(50)
.margin({
right:50
})
Text(this.contents)
.fontSize(20)
.margin({
top: 15
})
}
.margin({
bottom:30
})
}
}