• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# \@BuilderParam装饰器:引用\@Builder函数
2
3
4当开发者创建了自定义组件,并想对该组件添加特定功能时,例如在自定义组件中添加一个点击跳转操作。若直接在组件内嵌入事件方法,将会导致所有引入该自定义组件的地方均增加了该功能。为解决此问题,ArkUI引入了\@BuilderParam装饰器,\@BuilderParam用来装饰指向\@Builder方法的变量(@BuilderParam是用来承接@Builder函数的),开发者可在初始化自定义组件时对此属性进行赋值,为自定义组件增加特定的功能。该装饰器用于声明任意UI描述的一个元素,类似slot占位符。
5
6
7> **说明:**
8>
9> 从API version 9开始,该装饰器支持在ArkTS卡片中使用。
10
11
12## 装饰器使用说明
13
14
15### 初始化\@BuilderParam装饰的方法
16
17\@BuilderParam装饰的方法只能被自定义构建函数(\@Builder装饰的方法)初始化。
18
19- 使用所属自定义组件的自定义构建函数或者全局的自定义构建函数,在本地初始化\@BuilderParam。
20
21  ```ts
22  @Builder function overBuilder() {}
23
24  @Component
25  struct Child {
26    @Builder doNothingBuilder() {};
27
28    // 使用自定义组件的自定义构建函数初始化@BuilderParam
29    @BuilderParam customBuilderParam: () => void = this.doNothingBuilder;
30    // 使用全局自定义构建函数初始化@BuilderParam
31    @BuilderParam customOverBuilderParam: () => void = overBuilder;
32    build(){}
33  }
34  ```
35
36- 用父组件自定义构建函数初始化子组件\@BuilderParam装饰的方法。
37
38  ```ts
39  @Component
40  struct Child {
41    @Builder customBuilder() {}
42    // 使用父组件@Builder装饰的方法初始化子组件@BuilderParam
43    @BuilderParam customBuilderParam: () => void = this.customBuilder;
44
45    build() {
46      Column() {
47        this.customBuilderParam()
48      }
49    }
50  }
51
52  @Entry
53  @Component
54  struct Parent {
55    @Builder componentBuilder() {
56      Text(`Parent builder `)
57    }
58
59    build() {
60      Column() {
61        Child({ customBuilderParam: this.componentBuilder })
62      }
63    }
64  }
65  ```
66  **图1** 示例效果图
67
68  ![builderparam-demo1](figures/builderparam-demo1.png)
69
70
71- 需注意this指向正确。
72
73  以下示例中,Parent组件在调用this.componentBuilder()时,this指向其所属组件,即“Parent”。\@Builder componentBuilder()传给子组件\@BuilderParam customBuilderParam,在Child组件中调用this.customBuilderParam()时,this指向在Child的label,即“Child”。
74
75
76  ```ts
77  @Component
78  struct Child {
79    label: string = `Child`
80    @Builder customBuilder() {}
81    @Builder customChangeThisBuilder() {}
82    @BuilderParam customBuilderParam: () => void = this.customBuilder;
83    @BuilderParam customChangeThisBuilderParam: () => void = this.customChangeThisBuilder;
84
85    build() {
86      Column() {
87        this.customBuilderParam()
88        this.customChangeThisBuilderParam()
89      }
90    }
91  }
92
93  @Entry
94  @Component
95  struct Parent {
96    label: string = `Parent`
97
98    @Builder componentBuilder() {
99      Text(`${this.label}`)
100    }
101
102    build() {
103      Column() {
104        this.componentBuilder()
105        Child({ customBuilderParam: this.componentBuilder, customChangeThisBuilderParam: ():void=>{this.componentBuilder()} })
106      }
107    }
108  }
109  ```
110 **图2** 示例效果图
111
112 ![builderparam-demo2](figures/builderparam-demo2.png)
113
114
115## 使用场景
116
117
118### 参数初始化组件
119
120\@BuilderParam装饰的方法可以是有参数和无参数的两种形式,需与指向的\@Builder方法类型匹配。\@BuilderParam装饰的方法类型需要和\@Builder方法类型一致。
121
122
123```ts
124class Tmp{
125  label:string = ''
126}
127@Builder function overBuilder($$ : Tmp) {
128  Text($$.label)
129    .width(400)
130    .height(50)
131    .backgroundColor(Color.Green)
132}
133
134@Component
135struct Child {
136  label: string = 'Child'
137  @Builder customBuilder() {}
138  // 无参数类型,指向的componentBuilder也是无参数类型
139  @BuilderParam customBuilderParam: () => void = this.customBuilder;
140  // 有参数类型,指向的overBuilder也是有参数类型的方法
141  @BuilderParam customOverBuilderParam: ($$ : Tmp) => void = overBuilder;
142
143  build() {
144    Column() {
145      this.customBuilderParam()
146      this.customOverBuilderParam({label: 'global Builder label' } )
147    }
148  }
149}
150
151@Entry
152@Component
153struct Parent {
154  label: string = 'Parent'
155
156  @Builder componentBuilder() {
157    Text(`${this.label}`)
158  }
159
160  build() {
161    Column() {
162      this.componentBuilder()
163      Child({ customBuilderParam: this.componentBuilder, customOverBuilderParam: GlobalBuilder1 })
164    }
165  }
166}
167```
168**图3** 示例效果图
169
170![builderparam-demo3](figures/builderparam-demo3.png)
171
172
173### 尾随闭包初始化组件
174
175在自定义组件中使用\@BuilderParam装饰的属性时也可通过尾随闭包进行初始化。在初始化自定义组件时,组件后紧跟一个大括号“{}”形成尾随闭包场景。
176
177> **说明:**
178>
179>  - 此场景下自定义组件内有且仅有一个使用\@BuilderParam装饰的属性。
180>
181>  - 此场景下自定义组件不支持使用通用属性。
182
183开发者可以将尾随闭包内的内容看做\@Builder装饰的函数传给\@BuilderParam。示例如下:
184
185
186```ts
187// xxx.ets
188@Component
189struct CustomContainer {
190  @Prop header: string = '';
191  @Builder closerBuilder(){}
192  // 使用父组件的尾随闭包{}(@Builder装饰的方法)初始化子组件@BuilderParam
193  @BuilderParam closer: () => void = this.closerBuilder
194
195  build() {
196    Column() {
197      Text(this.header)
198        .fontSize(30)
199      this.closer()
200    }
201  }
202}
203
204@Builder function specificParam(label1: string, label2: string) {
205  Column() {
206    Text(label1)
207      .fontSize(30)
208    Text(label2)
209      .fontSize(30)
210  }
211}
212
213@Entry
214@Component
215struct CustomContainerUser {
216  @State text: string = 'header';
217
218  build() {
219    Column() {
220      // 创建CustomContainer,在创建CustomContainer时,通过其后紧跟一个大括号“{}”形成尾随闭包
221      // 作为传递给子组件CustomContainer @BuilderParam closer: () => void的参数
222      CustomContainer({ header: this.text }) {
223        Column() {
224          specificParam('testA', 'testB')
225        }.backgroundColor(Color.Yellow)
226        .onClick(() => {
227          this.text = 'changeHeader';
228        })
229      }
230    }
231  }
232}
233```
234**图4** 示例效果图
235
236![builderparam-demo4](figures/builderparam-demo4.png)
237