0
点赞
收藏
分享

微信扫一扫

鸿蒙之装饰器

鸿蒙中除了@State、@Prop、@Link、@Provide、@Consume、@Observerd、@ObjectLink用来修饰变量更改UI的装饰器外,还有很多其他的属性,都有着不同的作用,下面我们一起来看一下。

@Builder 装饰器

ArkUI提供了一种轻量的UI元素复用机制@Builder,该自定义组件内部UI结构固定,仅与使用方进行数据传递,开发者可以将重复使用的UI抽象成一个方法,在build方法里调用。 可以将如下代码:

build() {
  Column() {
    Text(this.name)
    Text(this.age)
  }
}

改为:

build() {
  this.columnBuilder(this.name, this.age)
}

@Builder
columnBuilder(name:string, age:string) {
  Column() {
    Text(name)
    Text(age)
  }
}

@LocalBuilder装饰器

使用@Builder做引用数据传递时,会考虑组件的父子关系,使用bind(this)之后,组件的父子关系和状态管理的父子关系并不一致。 @LocalBuilder拥有和局部@Builder相同的功能,且比局部@Builder能够更好的确定组件的父子关系和状态管理的父子关系。 代码如下:

class ReferenceType {
  paramString: string = '';
}

@Entry
@Component
struct Parent {
  @State variableValue: string = 'Hello World';

  @LocalBuilder
  citeLocalBuilder(params: ReferenceType) {
    Row() {
      Text(`UseStateVarByReference: ${params.paramString} `)
    }
  };

  build() {
    Column() {
      this.citeLocalBuilder({ paramString: this.variableValue });
      Button('Click me').onClick(() => {
        this.variableValue = 'Hi World';
      })
    }
  }
}

@BuilderParam装饰器

@BuilderParam为组件增加特定的功能。装饰器用于声明任意UI描述的一个元素,类似slot占位符。

代码如下: 使用所属自定义组件的自定义构建函数或者全局的自定义构建函数,在本地初始化@BuilderParam。

@Builder function overBuilder() {}

@Component
struct Child {
  @Builder doNothingBuilder() {};

  // 使用自定义组件的自定义构建函数初始化@BuilderParam
  @BuilderParam customBuilderParam: () => void = this.doNothingBuilder;
  // 使用全局自定义构建函数初始化@BuilderParam
  @BuilderParam customOverBuilderParam: () => void = overBuilder;
  build(){}
}

用父组件自定义构建函数初始化子组件@BuilderParam装饰的方法

@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 })
    }
  }
}

wrapBuilder:封装全局@Builder

在一个struct内使用多个全局@Builder函数来实现UI的不同效果时,多个全局@Builder函数会使代码维护起来非常困难,并且页面不整洁。这时候可以使用wrapBuilder来封装全局@Builer。 代码如下:

@Builder
function MyBuilder(value: string, size: number) {
  Text(value)
    .fontSize(size)
}

let globalBuilder: WrappedBuilder<[string, number]> = wrapBuilder(MyBuilder);

@Entry
@Component
struct Index {
  @State message: string = 'Hello World';

  build() {
    Row() {
      Column() {
        globalBuilder.builder(this.message, 50)
      }
      .width('100%')
    }
    .height('100%')
  }
}

@Styles装饰器

如果每个组件的样式都需要单独设置,在开发过程中会出现大量代码在进行重复样式设置,虽然可以复制粘贴,可以使用@Style装饰器,将公共的样式提炼出来变成自定义样式。 代码如下:

@Component
struct FancyUse {
  @State heightValue: number = 100
  @Styles fancy() {
    .height(this.heightValue)
    .backgroundColor(Color.Yellow)
    .onClick(() => {
      this.heightValue = 200
    })
  }
}

@Extend装饰器

@Styles用于样式的重用,在@Styles的基础上,可以使用@Extend用于扩展原生组件样式。 和@Styles不同,@Extend仅支持在全局定义,不支持在组件内部定义。 代码如下:

// @Extend(Text)可以支持Text的私有属性fontColor
@Extend(Text) function fancy () {
  .fontColor(Color.Red)
}
// superFancyText可以调用预定义的fancy
@Extend(Text) function superFancyText(size:number) {
    .fontSize(size)
    .fancy()
}

@AnimatableExtend装饰器

用于自定义可动画的属性方法,在这个属性方法中修改组件不可动画的属性。 代码如下:

@AnimatableExtend(Text)
function animatableWidth(width: number) {
  .width(width)
}

@Entry
@Component
struct AnimatablePropertyExample {
  @State textWidth: number = 80;

  build() {
    Column() {
      Text("AnimatableProperty")
        .animatableWidth(this.textWidth)
        .animation({ duration: 2000, curve: Curve.Ease })
      Button("Play")
        .onClick(() => {
          this.textWidth = this.textWidth == 80 ? 160 : 80;
        })
    }.width("100%")
    .padding(10)
  }
}

@Require装饰器

@Require是校验@Prop、@State、@Provide、@BuilderParam和普通变量(无状态装饰器修饰的变量)是否需要构造传参的一个装饰器。 当Child组件内使用@Require装饰器和@Prop、@State、@Provide、@BuilderParam和普通变量(无状态装饰器修饰的变量)结合使用时,父组件Index在构造Child时必须传参,否则编译不通过。

@Entry
@Component
struct Index {
  @State message: string = 'Hello World';

  @Builder buildTest() {
    Row() {
      Text('Hello, world')
        .fontSize(30)
    }
  }

  build() {
    Row() {
      Child({ regular_value: this.message, state_value: this.message, provide_value: this.message, initMessage: this.message, message: this.message,
        buildTest: this.buildTest, initBuildTest: this.buildTest })
    }
  }
}

@Component
struct Child {
  @Builder buildFunction() {
    Column() {
      Text('initBuilderParam')
        .fontSize(30)
    }
  }
  @Require regular_value: string = 'Hello';
  @Require @State state_value: string = "Hello";
  @Require @Provide provide_value: string = "Hello";
  @Require @BuilderParam buildTest: () => void;
  @Require @BuilderParam initBuildTest: () => void = this.buildFunction;
  @Require @Prop initMessage: string = 'Hello';
  @Require @Prop message: string;

  build() {
    Column() {
      Text(this.initMessage)
        .fontSize(30)
      Text(this.message)
        .fontSize(30)
      this.initBuildTest();
      this.buildTest();
    }
    .width('100%')
    .height('100%')
  }
}

举报

相关推荐

0 条评论