当前位置:   article > 正文

harmonyOS杂谈 - @BuilderParam装饰器:引用@Builder函数_builderparam property can only initialized by buil

builderparam property can only initialized by builder function.

@BuilderParam装饰器:引用@Builder函数

当开发者创建了自定义组件,并想对该组件添加特定功能时,例如在自定义组件中添加一个点击跳转操作。若直接在组件内嵌入事件方法,将会导致所有引入该自定义组件的地方均增加了该功能。为解决此问题,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()
    }
  }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27

运行结果:
在这里插入图片描述
用父组件自定义构建函数初始化子组件@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%')
  }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36

需注意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" })
    }
  }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

运行结果 :
在这里插入图片描述

尾随闭包初始化组件
在自定义组件中使用@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%')
  }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55

运行结果:
在这里插入图片描述
在这里插入图片描述

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Gausst松鼠会/article/detail/205894
推荐阅读
相关标签
  

闽ICP备14008679号