鸿蒙开发-几种装饰器

104 阅读3分钟

一. 自定义组件(跑题)

  • 定义组件

image.png

  • 使用组件

image.png

二. 自定义构建(渲染)函数 @Builder

  • 定义构建函数 (相当于把一段可复用的页面结构 封装到一起 和封装组件思想有点类似, 可以定义在全局或者组件内部

image.png

  • 使用构建函数

image.png

  • 组件内的构建函数, 不用加function 关键字, 使用的时候记得 this.

image.png

三. 样式相关装饰器

1. 通用公共样式 @Styles

  • 将公共的样式属性, 抽离出来

image.png

  • 使用:

image.png

  • 组件内的构建函数, 不用加function 关键字,(与组件内构建函数不同,使用时不需要加this.

image.png

2.特有属性装饰器 @Extend

  • 仅可以定义在全局 不能在组件内, 用于封装某些组件才有的样式属性, 比如fontSize、fontColor等。 语法@Extend(组件) function xxxx() { ...属性 }

image.png

四. @State 装饰用于驱动视图更新的变量

class Person {
  name: string
  age: number
  constructor(name: string, age: number) {
    this.name = name
    this.age = age
  }
}
@Entry
@Component
struct Decorator {
  @State message: string = 'Hello World'
  @State ps: Person[] = [new Person('Feng', 23)]
  count: number = 1

  build() {
    Row() {
      Column({space: 10}) {
        Text(this.message)
          .fontSize(50)
          .fontWeight(FontWeight.Bold)
          .onClick(() => {
            // 修改message
            this.message = '你好 世界'
          })
        Button('添加一个')
          .onClick(() => {
            this.ps.push(new Person('小'+this.count++, 23))
          })
        ForEach(
          this.ps,
          (item, index) => {
            Row() {
              Text(`${item.name} - ${item.age}`)
                .fontSize(30)
              Button('删除')
                .onClick(() => {
                  this.ps.splice(index, 1)
                })
            }
            .width('80%')
            .justifyContent(FlexAlign.SpaceBetween)
          }
        )
      }
      .width('100%')
      .height('100%')
      .justifyContent(FlexAlign.Start)
    }
    .height('100%')
  }
}

注意

  • @State装饰的变量, 必须进行初始化, 不能为空值。
  • @State支持Object、class、array、string、number、boolean、enum类型。
  • 嵌套对象中的属性修改, 不会触发视图更新。
  • 数组中的对象属性的修改, 不会触发视图更新。

五. @prop 和 @link 装饰器

父子组件需要数据同步时, 在子组件中可以使用 @Prop@Link 装饰器来装饰变量,@Prop为单项同步(只能修改父影响子), @Link为双向同步(子组件也可以对数据修改并且同步到父组件)

image.png

父组件: image.png 子组件:

image.png

1. @Prop传递的是变量的拷贝 @Link传递的是变量地址的引用

2. 两种装饰器装饰的变量不允许初始化(赋初值)

3. 在给@Link装饰的变量传递值的时候, 要使用 $ 符替代 this. , 代表传递变量的引用 image.png 4. @Prop只支持string/number/boolean/enum类型 , @Link支持string/number/boolean/enum/object/class以及他们的数组

六. @Provide(父组件) 和 @Consume(子组件) 装饰器

作用与@Link类似 可以实现双向数据同步, 但是可以跨组件层级 (比如爷爷-孙子), 并且不需要手动传递参数

@Provide提供:

image.png

@Consume接收: image.png

七. @Observed和@ObjectLink装饰器

用于处理深层嵌套对象和数组内对象属性变更 不触发页面更新的情况

  1. 给创建对象的类class上方 加上@Observed装饰器 image.png

  2. 定义一个B组件, 将内部嵌套对象或者数组元素对象作为变量传给B组件, 在组件内使用@ObjectLink装饰这个变量 image.png image.png @ObjectLink 用于接收@Observed装饰的类的实例

    @ObjectLink装饰器不能在@Entry装饰的自定义组件中使用。

    @Observed 只能修饰类,放在类定义前。@ObjectLink 只能修饰被@Observed修饰的class实例,必须指定类型。

八. 子组件调用父组件方法

子组件: image.png

父组件: 需要绑定this为当前组件 image.png