赞
踩
当开发者创建了自定义组件,并想对该组件添加特定功能时,例如在自定义组件中添加一个点击跳转操作。若直接在组件内嵌入事件方法,将会导致所有引入该自定义组件的地方均增加了该功能。为解决此问题,ArkUI引入了@BuilderParam装饰器,@BuilderParam用来装饰指向@Builder方法的变量,开发者可在初始化自定义组件时对此属性进行赋值,为自定义组件增加特定的功能。该装饰器用于声明任意UI描述的一个元素,类似slot占位符。
装饰器使用说明
初始化@BuilderParam装饰的方法
@BuilderParam装饰的方法只能被自定义构建函数(@Builder装饰的方法)初始化。
使用所属自定义组件的自定义构建函数或者全局的自定义构建函数,在本地初始化@BuilderParam。
@Builder function publicBuilderFunctionForBuilderParamDome() { } @Component struct testComponent { message: String = "子组件变量值"; @Builder builderFunction() { }; @Builder builderFunction2() { }; // @ts-ignore @BuilderParam publicBuilderFunctionParam: () => void = publicBuilderFunctionForBuilderParamDome(); // @ts-ignore @BuilderParam builderFunctionParam: () => void = this.builderFunction(); // @ts-ignore @BuilderParam builderFunctionParam2: () => void = this.builderFunction2(); build() { Column() { this.builderFunctionParam() this.builderFunctionParam2() } } }
运行结果:
用父组件自定义构建函数初始化子组件@BuilderParam装饰的方法。
@Entry @Component struct BuilderParamDome { message: string = "父组件变量值" @Builder privateBuilderFunction() { Text("父组件的构造函数") // 这里的this指的是 父组件BuilderParamDome Text(`父组件的message:${this.message}`) } build() { Row() { Column() { /** 这里的this指的是父组件BuilderParamDome * 所以调用的是BuilderParamDome中的privateBuilderFunction * 打印的是 父组件的构造函数 -> 父组件的message:父组件变量值 */ this.privateBuilderFunction() /** * 传递给子组件testComponent中builderFunctionParam 时候this变成了子组件testComponent * 所以调用的是testComponent中的builderFunction,然后子组件中调用this则显示的是子组件的message * 打印的是 父组件的构造函数 -> 父组件的message:子组件变量值 * * 后面再传递给子组件testComponent中builderFunctionParam2 时调用了 build 所以将父组件的this也一并传递给了子组件 * 打印的是 父组件的构造函数 -> 父组件的message:父组件变量值 */ testComponent({ builderFunctionParam: this.privateBuilderFunction, builderFunctionParam2: (): void => { this.privateBuilderFunction() } }) } .width('100%') } .height('100%') } }
需注意this指向正确。
以下示例中,BuilderParamDome组件在调用this.privateBuilderFunction()时,this指向其所属组件,即“BuilderParamDome”。@Builder BuilderParamDome()传给子组件@BuilderParam builderFunction,在testComponent组件中调用this.builderFunctionParam()时,this指向在testComponent的message,即“子组件变量值”。对于@BuilderParam builderFunctionParam2,在将this.privateBuilderFunction传给builderFunctionParam2时,调用bind绑定了this,因此其this.message指向BuilderParamDome的message。
运行结果:
使用场景
参数初始化组件
@BuilderParam装饰的方法可以是有参数和无参数的两种形式,需与指向的@Builder方法类型匹配。@BuilderParam装饰的方法类型需要和@Builder方法类型一致。
class Tmp { message: string = "" } @Builder function publicBuilderFunctionForBuilderParamDome($$: Tmp) { Text($$.message) .fontSize(20) .backgroundColor(Color.Red) } // 无参数的Builder 在使用@BuilderParam 注解装饰方法时 被装饰的方法也需要是无参数的 @BuilderParam builderFunctionParam: () => void = this.builderFunction; @BuilderParam builderFunctionParam2: () => void = this.builderFunction2; // 有参数的Builder 在使用@BuilderParam 注解装饰方法时 被装饰的方法也需要是有参数的 @BuilderParam publicBuilderFunctionParam2: ($$: Tmp) => void = publicBuilderFunctionForBuilderParamDome; build() { Column() { this.builderFunctionParam() this.builderFunctionParam2() this.publicBuilderFunctionParam2({ message: "publicBuilderFunctionForBuilderParamDome builder message" }) } }
运行结果 :
尾随闭包初始化组件
在自定义组件中使用@BuilderParam装饰的属性时也可通过尾随闭包进行初始化。在初始化自定义组件时,组件后紧跟一个大括号“{}”形成尾随闭包场景。
开发者可以将尾随闭包内的内容看做@Builder装饰的函数传给@BuilderParam。示例如下:
@Builder function publicBuilderFunctionForBuilderParamDome(param1: string, param2: string) { Column() { Text(param1) .fontSize(30) .fontColor(Color.Red) Text(param2) .fontSize(30) .fontColor(Color.Red) } } @Component struct testComponent { @Prop child: string = ""; @Builder builderFunction() { }; // 在尾随闭包初始化组件中自定义组件只允许有一个BuilderParam 注解表注的方法体,不然编译会不通过 @BuilderParam builderFunctionParam: () => void = this.builderFunction; build() { Column() { Text(this.child) .fontSize(30) this.builderFunctionParam() } } } @Entry @Component struct BuilderParamDome { @State message: string = "父组件变量值" build() { Row() { Column() { /** * 创建testComponent 在创建testComponent 是在()后面紧跟一个{}形成尾随闭包 * 作为传递给子组件estComponent @BuilderParam builderFunctionParam: () => void的参数 * */ testComponent({ child: this.message }) { Column() { publicBuilderFunctionForBuilderParamDome('公共构造函数参数A', '公共构造函数参数B') }.backgroundColor(Color.Yellow) .onClick(() => { this.message = '点击子组件修改后的标题'; }) } } .width('100%') } .height('100%') } }
运行结果:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。