示例代码:
@Entry
@Component
struct Index {
@State show: boolean = true
build() {
Column() {
Button('show')
.onClick(() => {
this.show = !this.show
})
if (this.show) {
ComponentA()
}
}
}
}
@Component
struct ComponentA {
build() {
Row() {
Text('Component A')
}
}
}
如示例代码所示,这是一个 Column 容器,里面有一个 Button 按钮,当点击这个按钮,会修改变量 show 的值,如果 show 为 true,就会渲染 ComponentA。
尽管他俩都是自定义组件,但是他俩的角色是不一样的。ComponentA 是被 Index 引用的,所以可以理解为 ComponentA 是 Index 的子组件,Index 加上了 @Entry 装饰器,也就是这个页面的入口组件。
因此,一个页面要加载,首先会加载入口组件 Index,一个组件要加载,先创建组件实例
。但是呢,示例创建出来不代表页面就有了,因为组件对应的页面是靠 build 函数绘制的,所以,在组件实例化以后必须执行 build 函数
。当 build 函数全部执行完成,页面才算绘制完成。在示例代码中,调用了 ComponentA,也就是说,在绘制的时候用到了别的组件,也就需要把 ComponentA 加载进来。加载 ComponentA 也需要先创建组件实例再去执行 build 函数。在入口组件当中,不管用到了多少个子组件,都必须把子组件实例创建出来,执行子组件 build 函数,再回过头执行入口组件的代码。当 build 函数内所有子组件包括它自己全部加载完成,页面才能真正绘制成功,也就可以展示页面
了。但是呢,页面加载出来,用户访问过程中,必然会去做各种各样的操作,不可能一直停留在这个页面,所以,当用户返回
或跳转
新页面,都有可能离开当前页面,当前页面就会从展示页面变成隐藏页面
。如果页面隐藏了,页面中组件是隐藏还是销毁呢?不一定,这去取决于当前页面在隐藏后有没有被销毁,假如我们利用 router.pushUrl() 去做跳转,新页面创建出来,会入栈,放到栈顶,原来的栈顶的会被压到栈内部,并没有被销毁,只是隐藏了,这时候,对应的组件还在;如果页面跳转采用 router.replaceUrl(),那么创建的新页面会压入栈中,放入栈顶,原来的栈顶直接销毁,也就会销毁组件
,入口组件都销毁了,也就会销毁子组件实例
。不仅仅是跳转,在返回时,会把栈顶的页面移除并销毁,然后把紧挨着栈顶的给挪上来,这时候原先栈顶的页面被销毁了,它所对应的组件也就被销毁了。反过来,如果页面还在,是不是说它里面所有组件也一定也在呢?可不一定,示例代码中,Button 按钮点击会修改 show 的值,show 默认是 true,所以对应的 ComponentA 一上来就会被渲染出来。但是如果现在点击按钮,会把 show 从 true 变成 false,ComponentA 就不能再渲染,本来已经渲染好了,现在不再需要,那么这个 ComponentA 会被销毁。所以页面还在,但组件没了。所以,用户在操作的过程中,很有可能会导致部分子组件被销毁,所以子组件有没有被销毁跟页面跟页面并没有必然的联系。
以上就是页面及组件从创建到销毁完整的生命周期。在这个过程中,Stage 模型提供了一些生命周期的钩子,允许我们在其中完成我们想要做的事:
-
组件实例创建成功以后,build 函数执行以前,这里呢有一个钩子,叫
aboutToAppear
。可以在这里面完成对一些数据的初始化,初始化以后,在 build 函数里就可以利用数据完成渲染。 -
在组件被销毁之前还有一个钩子,叫
aboutToDisappear
,可以在这里面完成数据持久化等保存操作。 -
页面展示之后有一个钩子,叫
onPageShow
。 -
页面隐藏之前有一个钩子,叫
onPageHide
。 -
当用户点击返回上一页时有一个钩子,叫
onBackPress
。
注:
onPageShow
、onPageHide
、onBackPress
都属于页面生命周期钩子,而aboutToAppear
、aboutToDisappear
则属于组件生命周期钩子。页面展示肯定是从入口组件开始的,因此页面生命周期钩子只能在加了@Entry
装饰器的入口组件中使用,普通的自定义组件里不能使用。而跟组件生命周期钩子可以在入口组件,也可以在任何普通自定义组件中使用。
如图所示:
总结:
页面和组件的生命周期主要有五个,aboutToAppear 是在组件创建之后然后 build 函数执行之前去触发,往往在这里做一些数据初始化和准备工作,准备好了以后 build 再去执行,就可以利用这些数据完成渲染。然后是页面的生命周期,页面展示出来就会有 onPageShow,页面被隐藏就会有 onPageHide,点击返回就会有 onBackPress,也可以在这三个里面做一些功能性的逻辑。最后是 aboutToDisappear,这个是在组件被销毁时,组件被销毁有可能一些关键性的数据需要去做保存,所以这里面可以做一些数据保存或者资源释放之类的操作。