Skip to content

自定义组件

自定义组件的生命周期

aboutToAppear

aboutToAppear 函数在创建自定义组件的新实例后,在执行其 build()函数之前执行。允许在 aboutToAppear 函数中改变状态变量,更改将在后续执行 build()函数中生效。实现自定义布局的自定义组件的 aboutToAppear 生命周期在布局过程中触发。

onDidBuild

onDidBuild 函数在执行自定义组件的 build()函数之后执行,开发者可以在这个阶段进行埋点数据上报等不影响实际 UI 的功能。不建议在 onDidBuild 函数中更改状态变量、使用 animateTo 等功能,这可能会导致不稳定的 UI 表现。

onPageShow

页面每次显示时触发一次,包括路由过程、应用进入前台等场景,仅@Entry 装饰的自定义组件作为页面时生效。

onPageHide

页面每次隐藏时触发一次,包括路由过程、应用进入后台等场景,仅@Entry 装饰的自定义组件作为页面时生效。

onBackPress

当用户点击返回按钮时触发,仅@Entry 装饰的自定义组件作为页面时生效。返回 true 表示页面自己处理返回逻辑,不进行页面路由;返回 false 表示使用默认的路由返回逻辑,不设置返回值按照 false 处理。

aboutToDisappear

函数在自定义组件析构销毁时执行。不允许在 aboutToDisappear 函数中改变状态变量,特别是@Link 变量的修改可能会导致应用程序行为不稳定。

示例

js
// xxx.ets
@Entry
@Component
struct IndexComponent {
  @State textColor: Color = Color.Black;


  onPageShow() {
    this.textColor = Color.Blue;
    console.info('IndexComponent onPageShow');
  }


  onPageHide() {
    this.textColor = Color.Transparent;
    console.info('IndexComponent onPageHide');
  }


  onBackPress() {
    this.textColor = Color.Red;
    console.info('IndexComponent onBackPress');
  }


  build() {
    Column() {
      Text('Hello World')
        .fontColor(this.textColor)
        .fontSize(30)
        .margin(30)
    }.width('100%')
  }
}

aboutToReuse

当一个可复用的自定义组件从复用缓存中重新加入到节点树时,触发 aboutToReuse 生命周期回调,并将组件的构造参数传递给 aboutToReuse。

js
// xxx.ets
export class Message {
  value: string | undefined;


  constructor(value: string) {
    this.value = value
  }
}


@Entry
@Component
struct Index {
  @State switch: boolean = true


  build() {
    Column() {
      Button('Hello World')
        .fontSize(50)
        .fontWeight(FontWeight.Bold)
        .onClick(() => {
          this.switch = !this.switch
        })
      if (this.switch) {
        Child({ message: new Message('Child') })
      }
    }
    .height("100%")
    .width('100%')
  }
}


@Reusable
@Component
struct Child {
  @State message: Message = new Message('AboutToReuse');


  aboutToReuse(params: Record<string, ESObject>) {
    console.info("Recycle Child")
    this.message = params.message as Message
  }


  build() {
    Column() {
      Text(this.message.value)
        .fontSize(20)
    }
    .borderWidth(2)
    .height(100)
  }
}

aboutToRecycle

组件的生命周期回调,在可复用组件从组件树上被加入到复用缓存之前调用。

js
// xxx.ets
export class Message {
  value: string | undefined;


  constructor(value: string) {
    this.value = value;
  }
}


@Entry
@Component
struct Index {
  @State switch: boolean = true;


  build() {
    Column() {
      Button('Hello World')
        .fontSize(50)
        .fontWeight(FontWeight.Bold)
        .onClick(() => {
          this.switch = !this.switch;
        })
      if (this.switch) {
        Child({ message: new Message('Child') })
      }
    }
    .height("100%")
    .width('100%')
  }
}


@Reusable
@Component
struct Child {
  @State message: Message = new Message('AboutToReuse');


  aboutToReuse(params: Record<string, ESObject>) {
    console.info("Reuse Child");
    this.message = params.message as Message;
  }


  aboutToRecycle() {
    //这里可以释放比较占内存的内容或其他非必要资源引用,避免一直占用内存,引发内存泄漏
    console.info("Recycle Child,child进入复用池中");
  }


  build() {
    Column() {
      Text(this.message.value)
        .fontSize(20)
    }
    .borderWidth(2)
    .height(100)
  }
}

onWillApplyTheme

onWillApplyTheme 函数用于获取当前组件上下文的 Theme 对象,在创建自定义组件的新实例后,在执行其 build()函数之前执行。允许在 onWillApplyTheme 函数中改变状态变量,更改将在后续执行 build()函数中生效。

js
// xxx.ets
import { CustomTheme, CustomColors, Theme, ThemeControl } from '@kit.ArkUI';


class BlueColors implements CustomColors {
  fontPrimary = Color.White;
  backgroundPrimary = Color.Blue;
  brand = Color.Blue; //品牌色
}


class PageCustomTheme implements CustomTheme {
  colors?: CustomColors;


  constructor(colors: CustomColors) {
    this.colors = colors;
  }
}
const BlueColorsTheme = new PageCustomTheme(new BlueColors());
// setDefaultTheme应该在应用入口页面调用或者在Ability中调用。
ThemeControl.setDefaultTheme(BlueColorsTheme);


@Entry
@Component
struct IndexComponent {
  @State textColor: ResourceColor = $r('sys.color.font_primary');
  @State columBgColor: ResourceColor = $r('sys.color.background_primary');


  // onWillApplyTheme中可获取当前组件上下文的Theme对象。此处在onWillApplyTheme中将状态变量textColor、columBgColor,赋值为当前使用的Theme对象(BlueColorsTheme)中的配色。
  onWillApplyTheme(theme: Theme) {
    this.textColor = theme.colors.fontPrimary;
    this.columBgColor = theme.colors.backgroundPrimary;
    console.info('IndexComponent onWillApplyTheme');
  }


  build() {
    Column() {
      // 组件初始值配色样式
      Column() {
        Text('Hello World')
          .fontColor($r('sys.color.font_primary'))
          .fontSize(30)
      }
      .width('100%')
      .height('25%')
      .borderRadius('10vp')
      .backgroundColor($r('sys.color.background_primary'))


      // 组件颜色生效为onWillApplyTheme中配置颜色。
      Column() {
        Text('onWillApplyTheme')
          .fontColor(this.textColor)
          .fontSize(30)
        Text('Hello World')
          .fontColor(this.textColor)
          .fontSize(30)
      }
      .width('100%')
      .height('25%')
      .borderRadius('10vp')
      .backgroundColor(this.columBgColor)
    }
    .padding('16vp')
    .backgroundColor('#dcdcdc')
    .width('100%')
    .height('100%')
  }
}

自定义组件内置方法

自定义组件内置方法是由 ArkUI 开发框架提供给应用开发者的,定义在自定义组件基类上的 API。应用开发者可以在自定义组件的实例上调用对应的 API 以获取当前自定义组件实例相关的信息。例如,查询当前自定义组件上下文的 UIContext 信息。

getUIContext

获取 UIContext 对象。

js

import { UIContext } from '@kit.ArkUI';


@Entry
@Component
struct MyComponent {
  aboutToAppear() {
    let uiContext: UIContext = this.getUIContext();
  }


  build() {
    // ...
  }
}

getUniqueId

获取当前 Component 的 UniqueId。UniqueId 为系统为每个组件分配的 Id,可保证当前应用中的唯一性。若在组件对应的节点未创建或已销毁时获取,返回无效 UniqueId:-1。

js

@Entry
@Component
struct MyComponent {
  aboutToAppear() {
    let uniqueId: number = this.getUniqueId();
  }


  build() {
    // ...
  }
}

queryNavDestinationInfo

查询自定义组件所属的 NavDestination 信息,仅当自定义组件在 NavDestination 的内部时才生效。

js

import { uiObserver } from '@kit.ArkUI';


@Component
export struct NavDestinationExample {
  build() {
    NavDestination() {
      MyComponent()
    }
  }
}


@Component
struct MyComponent {
  navDesInfo: uiObserver.NavDestinationInfo | undefined


  aboutToAppear() {
    // this指代MyComponent自定义节点,并从该节点向上查找其最近的一个类型为NavDestination的父亲节点
    this.navDesInfo = this.queryNavDestinationInfo();
    console.log('get navDestinationInfo: ' + JSON.stringify(this.navDesInfo));
  }


  build() {
    // ...
  }
}

queryNavigationInfo

查询自定义组件所属的 Navigation 信息。

js
// index.ets
import { uiObserver } from '@kit.ArkUI';


@Entry
@Component
struct MainPage {
  pathStack: NavPathStack = new NavPathStack();


  build() {
    Navigation(this.pathStack) {
      // ...
    }.id("NavigationId")
  }
}




@Component
export struct PageOne {
  pathStack: NavPathStack = new NavPathStack();


  aboutToAppear() {
    // this指代PageOne自定义节点,并从该节点向上查找其最近的一个类型为Navigation的父亲节点
    let navigationInfo: uiObserver.NavigationInfo | undefined = this.queryNavigationInfo();
    console.log('get navigationInfo: ' + JSON.stringify(navigationInfo));
    if (navigationInfo !== undefined) {
      this.pathStack = navigationInfo.pathStack;
    }
  }


  build() {
    NavDestination() {
      // ...
    }.title('PageOne')
  }
}

queryRouterPageInfo

获取 RouterPageInfo 实例对象。

js
import { uiObserver } from '@kit.ArkUI';


@Entry
@Component
struct MyComponent {
  aboutToAppear() {
    let info: uiObserver.RouterPageInfo | undefined = this.queryRouterPageInfo();
  }


  build() {
    // ...
  }
}