【HarmonyOS】Stage 模型 - 页面及组件生命周期

示例代码:

@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 模型提供了一些生命周期的钩子,允许我们在其中完成我们想要做的事:

  1. 组件实例创建成功以后,build 函数执行以前,这里呢有一个钩子,叫 aboutToAppear。可以在这里面完成对一些数据的初始化,初始化以后,在 build 函数里就可以利用数据完成渲染。

  2. 在组件被销毁之前还有一个钩子,叫 aboutToDisappear,可以在这里面完成数据持久化等保存操作。

  3. 页面展示之后有一个钩子,叫 onPageShow

  4. 页面隐藏之前有一个钩子,叫 onPageHide

  5. 当用户点击返回上一页时有一个钩子,叫 onBackPress

注:onPageShowonPageHideonBackPress 都属于页面生命周期钩子,而 aboutToAppearaboutToDisappear 则属于组件生命周期钩子。页面展示肯定是从入口组件开始的,因此页面生命周期钩子只能在加了 @Entry 装饰器的入口组件中使用,普通的自定义组件里不能使用。而跟组件生命周期钩子可以在入口组件,也可以在任何普通自定义组件中使用。

如图所示:
请添加图片描述

总结:

页面和组件的生命周期主要有五个,aboutToAppear 是在组件创建之后然后 build 函数执行之前去触发,往往在这里做一些数据初始化和准备工作,准备好了以后 build 再去执行,就可以利用这些数据完成渲染。然后是页面的生命周期,页面展示出来就会有 onPageShow,页面被隐藏就会有 onPageHide,点击返回就会有 onBackPress,也可以在这三个里面做一些功能性的逻辑。最后是 aboutToDisappear,这个是在组件被销毁时,组件被销毁有可能一些关键性的数据需要去做保存,所以这里面可以做一些数据保存或者资源释放之类的操作。

  • 8
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

吴同学是个程序员

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值