鸿蒙中除了@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%')
}
}