ETS装饰器学习之State、Prop、Link 原创

droidzxy
发布于 2022-11-7 12:20
浏览
0收藏

在学习声明式UI框架ArkUI的过程中,会遇到装饰器的概念,不管是简单的示例页面还是复杂的大程序,都离不开装饰器的使用,为了帮助自己对装饰器有一个基本的了解,并能够熟练的使用,所以专门针对ets装饰器系统的学习了一下,并整理成简单的笔记,以便健忘的我随时回来复习一下。


本文主要介绍@State、@Prop和@Link,@State表示组件内部状态数据,@Prop装饰的变量必须是定义在子组件中,并且在父组件调用的时候进行参数赋值,@Link装饰的变量可以和父组件的@State变量建立双向数据绑定。


@State

@State装饰的变量是组件内部的状态数据,当这些状态数据被修改时,将会调用所在组件的build方法进行UI刷新。
@State状态数据具有以下特征:

  • 支持多种类型数据:支持class、number、boolean、string强类型数据的值类型和引用类型,以及这些强类型构成的数组,即Array<class>、Array<string>、Array<boolean>、Array<number>。不支持object和any。
  • 支持多实例:组件不同实例的内部状态数据独立。
  • 内部私有:标记为@State的属性是私有变量,只能在组件内访问。
  • 需要本地初始化:必须为所有@State变量分配初始值,变量未初始化可能导致未定义的框架异常行为。
  • 创建自定义组件时支持通过状态变量名设置初始值:在创建组件实例时,可以通过变量名显式指定@State状态变量的初始值。

示例代码:

class Model {
  value: string

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

@Entry
@Component
struct Index {
  @State title: Model = { value: 'Introduction' }
  @State index: number = 2
  @State message: string = 'This is an example for State'
  @State items : Array<string> = ['First item','Second item','Third item']

  build() {
    Row() {
      Column() {
        Text(this.index.toString())
          .fontSize(50)
          .width('100%')
        Text(this.title.value)
          .fontSize(30)
          .fontWeight(FontWeight.Bold)
          .width('100%')
          .textAlign(TextAlign.Start)
        Text(this.message)
          .fontSize(25)
          .width('100%')

        ForEach(this.items, item => {
          Text(item.toString()).fontSize(18).padding(10)
            .width('100%')
            .textAlign(TextAlign.Start)
        }, item => item.toString())

        SubComponent({num: 20})

      }
      .width('100%')
    }
    .height('100%')
  }
}


@Component
struct SubComponent {
  @Prop num: number

  build() {
    Column() {
      Text(`SubComponent num ${this.num} `).fontSize(28)
        .fontColor(Color.White)
    }
    .width('100%')
    .backgroundColor(Color.Gray)

  }
}

效果预览:

ETS装饰器学习之State、Prop、Link-鸿蒙开发者社区

上面示例,分别针对state修饰的变量按照class、number、string、Array<string>
类型进行了实践,需要注意的是必须本地初始化。


@Prop

@Prop与@State有相同的语义,但初始化方式不同。@Prop装饰的变量必须使用其父组件提供的@State变量进行初始化,允许组件内部修改@Prop变量,但更改不会通知给父组件,即@Prop属于单向数据绑定。
@Prop状态数据具有以下特征:

  • 支持简单类型:仅支持number、string、boolean简单类型;
  • 私有:仅在组件内访问;
  • 支持多个实例:一个组件中可以定义多个标有@Prop的属性;
  • 创建自定义组件时将值传递给@Prop变量进行初始化:在创建组件的新实例时,必须初始化所有@Prop变量,不支持在组件内部进行初始化。

示例代码:

@Entry
@Component
struct Index {
  @State message: string = 'Prop'

  build() {
    Row() {
      Column() {
        Text(this.message)
          .fontSize(50)
          .fontWeight(FontWeight.Bold)

        SubComponent({count : 20})
      }
      .width('100%')
    }
    .height('100%')
  }
}

@Component
struct SubComponent {
  @Prop count: number
  build(){
    Text("subcomponent member:" + this.count)
      .fontSize(25)
  }
}


效果预览:

ETS装饰器学习之State、Prop、Link-鸿蒙开发者社区

需要注意的是,在子组件中prop变量不能初始化,在父组件调用时,必须给变量赋值。


@Link

@Link装饰的变量可以和父组件的@State变量建立双向数据绑定:

  • 支持多种类型:@Link变量的值与@State变量的类型相同,即class、number、string、boolean或这些类型的数组;
  • 私有:仅在组件内访问;
  • 单个数据源:初始化@Link变量的父组件的变量必须是@State变量;
  • 双向通信:子组件对@Link变量的更改将同步修改父组件的@State变量;
  • 创建自定义组件时需要将变量的引用传递给@Link变量:在创建组件的新实例时,必须使用命名参数初始化所有@Link变量。@Link变量可以使用@State变量或@Link变量的引用进行初始化,@State变量可以通过’$'操作符创建引用。

示例代码:


@Entry
@Component
struct Index {
  @State count: number = 0

  build() {
    Row() {
      Column() {
        Text('count=' + this.count)
          .fontSize(50)
          .fontWeight(FontWeight.Bold)

        SubComponent({ subCount: $count })
      }
      .width('100%')
    }
    .height('100%')
  }
}

@Component
struct SubComponent {
  @Link subCount: number

  build() {
    Button('subCount=' + this.subCount)
      .margin(15)
      .onClick(() => {
        this.subCount += 1
      })
  }
}

效果预览:

ETS装饰器学习之State、Prop、Link-鸿蒙开发者社区

需要注意的是,@Link变量不能在组件内部进行初始化,@State变量要通过’$'操作符创建引用。

©著作权归作者所有,如需转载,请注明出处,否则将追究法律责任
标签
3
收藏
回复
举报
回复
    相关推荐