鸿蒙ArkTS中的一些常用装饰器总结

1,067 阅读5分钟

本文正在参加华为鸿蒙有奖征文征文活动

我总结了全部关于鸿蒙的装饰器,简单地一一介绍一下:

@Entry、@Component、@State、@Prop、@Link、@Builder、@Style、@Extends、@BuilderParam、@Observe、@objectLink、@Provide、@Consume、@Watch;
其它:@CustomDialog、@Preview、@Reusable、@Concurrent、@Track;

  • @Component表示自定义组件;

  • @Entry用于装饰自定义组件,表示自定义组件的入口,加了@Entry才能算是一个页面,否则只能算组件;

  • @State装饰器,使得变量变为状态变量,影响UI(数据变化,UI变化)

  • @Prop装饰的变量和父组件建立单向的同步关系:

    • 父组件的@State数据变化,会同步到子组件@Prop

    • 具体用法

//父组件:Parent
   @State num:number = 0
     build(){
        Son({num:this.num})
     }
//子组件:Son
   @Prop num:number
   
  • @State修饰的变量,api9不能初始化,api11能初始化

  • @Link装饰的变量与其父组件中的数据源共享相同的值。

    • 父组件的@State数据变化,会同步到子组件@Link数据

    • 子组件@link数据变化,会同步到父组件@State数据

    • 具体用法

//父组件:Parent
    @State num:number = 0
     build(){
         Son({num:$num})//api9必须使用$,api11开始也可以使用this了
     }
//子组件:Son
    @Link num:number
  • @Link修饰的变量,api9不能初始化,api11能初始化

  • @Styles装饰器:定义组件重用样式 (多个组件通用的样式),用于封装重复的通用样式代码。

    如果多个不同类型的组件,有着相同的样式,例如宽高,背景色,字体大小。那么就可以将这下相同的样式代码抽取到一个@Styles装饰器修饰的方法中,供大家复用。

    支持全局和局部定义:

// 全局
    @Styles function functionName() { ... } //styles方法不能调用另一个styles方法***
    
// 在组件内
    @Component
    struct FancyUse {
      @Styles fancy() {
        .height(100)
      }
    }
  • @Extend装饰器:定义扩展组件样式 (某一种组件自己的样式,私有属性),用于扩展原生组件样式。

    如果同一类型的组件,有着很多相同的样式,例如按钮的类型,点击事件等。那么就可以将这些重复代码,抽过去到一个@Extend装饰器修饰的方法中,供此组件使用。

    ==仅支持全局定义==:(因为它相当于是给所有的此类组件使用)

// @Extend(Text)可以支持Text的私有属性fontColor
   @Extend(Text) function fancy () {
      .fontColor(Color.Red)
    }
// superFancyText可以调用预定义的fancy
   @Extend(Text) function superFancyText(size:number) { //Extend方法可以调用另一个Extend方法
     .fontSize(size)
     .fancy()
   }
  • @Builder装饰器:自定义构建函数

    @Builder装饰器,用于封装重复的,复杂UI结构代码,例如List中的ListItem的布局结构,一般比较复杂就可以抽取到@Builder装饰的函数中

    @Builder所装饰的函数遵循build()函数语法规则,开发者可以将重复使用的UI元素抽象成一个方法,在build方法里调用。

    支持全局定义和局部定义:

//既然调用是通过this调用,那么说明是在组件内部定义
//组件内部定义不需要关键字function
   @Builder MyBuilderFunction() { ... }
    ​
//全局定义
   MyGlobalBuilderFunction()
  • @BuilderParam装饰器:引用@Builder函数

    当开发者创建了自定义组件,并想对该组件添加特定功能时,例如在自定义组件中添加一个点击跳转操作。若直接在组件内嵌入事件方法,将会导致所有引入该自定义组件的地方均增加了该功能。

    为解决此问题,ArkUI引入了@BuilderParam装饰器,该装饰器用于声明任意UI描述的一个元素,==类似slot占位符==。

    • 使得自定义组件更加灵活

    代码:

    @Component
    struct Child {
      @Builder customBuilder() {}
      // 使用父组件@Builder装饰的方法初始化子组件@BuilderParam
      @BuilderParam customBuilderParam: () => void = this.customBuilder;
    ​
      build() {
        Column() {
          this.customBuilderParam()
        }
      }
    }
    ​
    @Entry
    @Component
    struct Parent {
      @Builder componentBuilder() {
        Text(`Parent builder `)
      }
    ​
      build() {
        Column() {
          Child({ customBuilderParam: this.componentBuilder })
        }
      }
    }
  • Provide和Consume

    @Provide和@Consume,用于祖先与后代组件的双向数据同步,实现跨层级传递

    • ==理解==:@Provide装饰器的变量是在祖先组件中,可以理解为被“提供”给后代的状态变量。@Consume装饰的变量是在后代组件中,去“消费”数据

    语法特点:

  • @Provide和@Consume可以通过相同的变量名或者相同的变量别名绑定

// 通过相同的变量名绑定
   @Provide a: number = 0; //祖先组件中定义
   @Consume a: number;  //子孙组件中定义
       
// 通过相同的变量别名绑定
   @Provide('a') b: number = 0;//参数即为别名
   @Consume('a') c: number;
  • ObjectLink和Observed

    @ObjectLink和@Observed类装饰器用于在涉及嵌套对象或数组的场景中进行双向数据同步:

    • 被@Observed装饰的类,可以被观察到属性的变化;
    • 子组件中@ObjectLink装饰器装饰的状态变量用于接收@Observed装饰的类的实例,和父组件中对应的状态变量建立双向数据绑定。这个实例可以是数组中的被@Observed装饰的项,或者是class object中的属性,这个属性同样也需要被@Observed装饰。
    • 单独使用@Observed是没有任何作用的,需要搭配@ObjectLink或者@Prop使用。
  • Watch

概述

@Watch应用于==对状态变量的监听==。如果开发者需要关注某个状态变量的值是否改变,可以使用@Watch为状态变量设置回调函数。

@Watch用于监听状态变量的变化,当状态变量变化时,@Watch的回调方法将被调用

代码:

@Component
struct TotalView {
  @Prop @Watch('onCountUpdated') count: number = 0;
  @State total: number = 0;
  // 该函数是自定义组件的成员函数
  // @Watch 回调
  // propName是被watch的属性名
  // 多个状态绑定同一个@Watch回调时,通过propName区分到底是哪个状态改变了
  onCountUpdated(propName: string): void {
    this.total += this.count;
  }

  build() {
    Text(`Total: ${this.total}`)
  }
}

@Entry
@Component
struct CountModifier {
  @State count: number = 0;

  build() {
    Column() {
      Button('add to basket')
        .onClick(() => {
          this.count++
        })
      TotalView({ count: this.count })
    }
  }
}

其它:

  • @CustomDialog:自定义弹窗,结合CustomDialogController使用。
  • @Preview:用于预览器预览页面。
  • @Reusable:复用标识,用于划分自定义组件的复用组。当组件回收复用时,复用框架将根据组件的reuseId来划分组件的复用组。从API Version 10开始支持。
  • @Concurrent装饰器:校验并发函数。在使用TaskPool时,执行的并发函数需要使用该装饰器修饰,否则无法通过相关校验。
  • @Track:应用于class对象的属性级更新。@Track装饰的属性变化时,只会触发该属性关联的UI更新。