首页 > 其他分享 >鸿蒙自定义组件生命周期

鸿蒙自定义组件生命周期

时间:2024-11-10 22:19:13浏览次数:1  
标签:Index 生命周期 自定义 鸿蒙 Child 组件 aboutToDisappear 页面

在开始之前,我们先明确自定义组件和页面的关系:

  • 自定义组件:@Component装饰的UI单元,可以组合多个系统组件实现UI的复用,可以调用组件的生命周期。
  • 页面:即应用的UI页面。可以由一个或者多个自定义组件组成,@Entry装饰的自定义组件为页面的入口组件,即页面的根节点,一个页面有且仅能有一个@Entry。只有被@Entry装饰的组件才可以调用页面的生命周期。

页面生命周期,即被@Entry装饰的组件生命周期,提供以下生命周期接口:

  • onPageShow:页面每次显示时触发一次,包括路由过程、应用进入前台等场景。
  • onPageHide:页面每次隐藏时触发一次,包括路由过程、应用进入后台等场景。
  • onBackPress:当用户点击返回按钮时触发。

组件生命周期,即一般用@Component装饰的自定义组件的生命周期,提供以下生命周期接口:

  • aboutToAppear:组件即将出现时回调该接口,具体时机为在创建自定义组件的新实例后,在执行其build()函数之前执行。
  • onDidBuild:组件build()函数执行完成之后回调该接口,不建议在onDidBuild函数中更改状态变量、使用animateTo等功能,这可能会导致不稳定的UI表现。
  • aboutToDisappear:aboutToDisappear函数在自定义组件析构销毁之前执行。不允许在aboutToDisappear函数中改变状态变量,特别是@Link变量的修改可能会导致应用程序行为不稳定。

生命周期流程如下图所示,下图展示的是被@Entry装饰的组件(页面)生命周期。
img1
以下示例展示了生命周期的调用时机:

// 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';
      })
  }
}

// page.ets
@Entry
@Component
struct page {
  @State textColor: Color = Color.Black;
  @State num: number = 0;

  onPageShow() {
    this.num = 5;
  }

  onPageHide() {
    console.log("page onPageHide");
  }

  onBackPress() { // 不设置返回值按照false处理
    this.textColor = Color.Grey;
    this.num = 0;
  }

  aboutToAppear() {
    this.textColor = Color.Blue;
  }

  build() {
    Column() {
      Text(`num 的值为:${this.num}`)
        .fontSize(30)
        .fontWeight(FontWeight.Bold)
        .fontColor(this.textColor)
        .margin(20)
        .onClick(() => {
          this.num += 5;
        })
    }
    .width('100%')
  }
}

以上示例中,Index页面包含两个自定义组件,一个是被@Entry装饰的MyComponent,也是页面的入口组件,即页面的根节点;一个是Child,是MyComponent的子组件。只有@Entry装饰的节点才可以使页面级别的生命周期方法生效,因此在MyComponent中声明当前Index页面的页面生命周期函数(onPageShow / onPageHide / onBackPress)。MyComponent和其子组件Child分别声明了各自的组件级别生命周期函数(aboutToAppear / onDidBuild/aboutToDisappear)。

  • 应用冷启动的初始化流程为:MyComponent aboutToAppear --> MyComponent build --> MyComponent onDidBuild--> Child aboutToAppear --> Child build --> Child onDidBuild --> Index onPageShow。
  • 点击“delete Child”,if绑定的this.showChild变成false,删除Child组件,会执行Child aboutToDisappear方法。
  • 点击“push to next page”,调用router.pushUrl接口,跳转到另外一个页面,当前Index页面隐藏,执行页面生命周期Index onPageHide。此处调用的是router.pushUrl接口,Index页面被隐藏,并没有销毁,所以只调用onPageHide。跳转到新页面后,执行初始化新页面的生命周期的流程。
  • 如果调用的是router.replaceUrl,则当前Index页面被销毁,执行的生命周期流程将变为:Index onPageHide --> MyComponent aboutToDisappear --> Child aboutToDisappear。上文已经提到,组件的销毁是从组件树上直接摘下子树,所以先调用父组件的aboutToDisappear,再调用子组件的aboutToDisappear,然后执行初始化新页面的生命周期流程。
  • 点击返回按钮,触发页面生命周期Index onBackPress,且触发返回一个页面后会导致当前Index页面被销毁。
  • 最小化应用或者应用进入后台,触发Index onPageHide。当前Index页面没有被销毁,所以并不会执行组件的aboutToDisappear。应用回到前台,执行Index onPageShow。
  • 退出应用,执行Index onPageHide --> MyComponent aboutToDisappear --> Child aboutToDisappear。

标签:Index,生命周期,自定义,鸿蒙,Child,组件,aboutToDisappear,页面
From: https://www.cnblogs.com/zhaloe/p/18538118

相关文章

  • 鸿蒙的进击之路
    1.题记:为什么要写鸿蒙,因为她是华为的,为什么是华为就要写,因为华为背负了国人太多太多的包袱,或点赞或抨击。我是强烈支持华为的,但我会客观公正地去评价华为的产品,就比如这篇博文,要写的是华为鸿蒙系统的进击之路。2.鸿蒙名字的来由2.1鸿蒙”的原意“鸿蒙”最早出自......
  • 鸿蒙网络编程系列 43- 仓颉版 HttpRequest 下载文件示例
    HttpRequest文件下载示例编写下面详细介绍创建该示例的步骤(确保DevEcoStudio已安装仓颉插件)。步骤1:创建[Cangjie]EmptyAbility项目。步骤2:在module.json5配置文件加上对权限的声明:"requestPermissions":[{"name":"ohos.permission.INTERNET"}]这里添加了访问......
  • Flutter 与鸿蒙三方库 ohos 的适配
    Flutter与鸿蒙三方库ohos的适配一、前期准备flutter开发环境调下载待适配的三方插件(官方插件库地址https://pub.dev/)备注:原生插件目录:lib:是对接dart端代码的入口,由此文件接收到参数后,通过channel将数据发送到原生端;android:安卓端代码实现目录;ios:ios原生端实现目录;ex......
  • 鸿蒙 next 实现隐藏顶部 StatusBar
    鸿蒙next实现隐藏顶部StatusBar在一些业务场景中需要用背景图片或者颜色去自定义顶部StatusBar的背景,但鸿蒙next中默认是不可以覆盖的,所以这里介绍实现隐藏顶部StatusBar的实现步骤。1.在应用启动页中开启沉浸式布局。开启沉浸式布局的效果就是会让你可以自定义顶部状......
  • 【开源鸿蒙】OpenHarmony 5.0 轻量系统最小开发环境搭建
    本文将会介绍,如何下载源代码和工具链,让磁盘占用尽可能小的同时,还可以进行轻量系统上的OpenHarmony开发(进行源码编译构建)。最终实现了将磁盘占用从完整源码的67G减少到了15G,不到完整源码的四分之一磁盘占用!一、写在前面——为什么写本篇内容OpenHarmony5.0发布了,该版本系......
  • 自定义类型那点事儿
    自定义类型:结构体,位段,枚举,联合目录自定义类型:结构体,位段,枚举,联合结构体1.结构体的声明2.结构体的特殊声明3.结构体的自引用4.结构体变量的定义和初始化5.结构体内存对齐6.修改默认对齐数7.结构体传参位段1.什么是位段?2.位段的内存分配3.位段的跨平台问题枚举......
  • 鸿蒙HarmonyOS(ArkTS基础篇大合集!)
    目录ArkTS语言1.初识ArkTS语言......
  • 鸿蒙Navigation页面生命周期
    Navigation作为路由容器,其生命周期承载在NavDestination组件上,以组件事件的形式开放。其生命周期大致可分为三类,自定义组件生命周期、通用组件生命周期和自有生命周期。其中,aboutToAppear和aboutToDisappear是自定义组件的生命周期(NavDestination外层包含的自定义组件),OnAppear和......
  • 在Qt中创建和使用自定义控件类时,可能会遇到以下一些常见问题
    在Qt中创建和使用自定义控件类时,可能会遇到以下一些常见问题:一、布局相关问题大小调整不正确:问题描述:自定义控件在不同的布局环境下,可能无法按照预期调整大小。例如,当将自定义控件添加到一个水平布局或垂直布局中时,它可能不会随着布局的拉伸或收缩而正确地改变自身大小。原......
  • 自定义圆形进度条控件
    以下将以创建一个简单的为例,详细说明在Qt中创建自定义控件的步骤:一、创建项目首先,打开QtCreator并创建一个新的QtWidgetsApplication项目。按照向导完成项目的基本设置,比如项目名称、存储路径等。二、创建自定义控件类继承基础控件类:在项目中创建一个新的C++类,命名为Ci......