1e41f4b71Sopenharmony_ci# \@Builder装饰器:自定义构建函数
2e41f4b71Sopenharmony_ci
3e41f4b71Sopenharmony_ciArkUI提供了一种轻量的UI元素复用机制\@Builder,该自定义组件内部UI结构固定,仅与使用方进行数据传递,开发者可以将重复使用的UI元素抽象成一个方法,在build方法里调用。
4e41f4b71Sopenharmony_ci
5e41f4b71Sopenharmony_ci为了简化语言,我们将\@Builder装饰的函数也称为“自定义构建函数”。
6e41f4b71Sopenharmony_ci
7e41f4b71Sopenharmony_ci
8e41f4b71Sopenharmony_ci> **说明:**
9e41f4b71Sopenharmony_ci>
10e41f4b71Sopenharmony_ci> 从API version 9开始,该装饰器支持在ArkTS卡片中使用。
11e41f4b71Sopenharmony_ci>
12e41f4b71Sopenharmony_ci> 从API version 11开始,该装饰器支持在原子化服务中使用。
13e41f4b71Sopenharmony_ci
14e41f4b71Sopenharmony_ci## 限制条件
15e41f4b71Sopenharmony_ci
16e41f4b71Sopenharmony_ci- \@Builder通过按引用传递的方式传入参数,才会触发动态渲染UI,并且参数只能是一个。
17e41f4b71Sopenharmony_ci
18e41f4b71Sopenharmony_ci- \@Builder如果传入的参数是两个或两个以上,不会触发动态渲染UI。
19e41f4b71Sopenharmony_ci
20e41f4b71Sopenharmony_ci- \@Builder传入的参数中同时包含按值传递和按引用传递两种方式,不会触发动态渲染UI。
21e41f4b71Sopenharmony_ci
22e41f4b71Sopenharmony_ci- \@Builder的参数必须按照对象字面量的形式,把所需要的属性一一传入,才会触发动态渲染UI。
23e41f4b71Sopenharmony_ci
24e41f4b71Sopenharmony_ci## 装饰器使用说明
25e41f4b71Sopenharmony_ci
26e41f4b71Sopenharmony_ci### 私有自定义构建函数
27e41f4b71Sopenharmony_ci
28e41f4b71Sopenharmony_ci定义的语法:
29e41f4b71Sopenharmony_ci
30e41f4b71Sopenharmony_ci```ts
31e41f4b71Sopenharmony_ci@Builder MyBuilderFunction() {}
32e41f4b71Sopenharmony_ci```
33e41f4b71Sopenharmony_ci
34e41f4b71Sopenharmony_ci使用方法:
35e41f4b71Sopenharmony_ci
36e41f4b71Sopenharmony_ci```ts
37e41f4b71Sopenharmony_cithis.MyBuilderFunction()
38e41f4b71Sopenharmony_ci```
39e41f4b71Sopenharmony_ci
40e41f4b71Sopenharmony_ci- 允许在自定义组件内定义一个或多个@Builder方法,该方法被认为是该组件的私有、特殊类型的成员函数。
41e41f4b71Sopenharmony_ci
42e41f4b71Sopenharmony_ci- 私有自定义构建函数允许在自定义组件内、build方法和其他自定义构建函数中调用。
43e41f4b71Sopenharmony_ci
44e41f4b71Sopenharmony_ci- 在自定义函数体中,this指代当前所属组件,组件的状态变量可以在自定义构建函数内访问。建议通过this访问自定义组件的状态变量而不是参数传递。
45e41f4b71Sopenharmony_ci
46e41f4b71Sopenharmony_ci
47e41f4b71Sopenharmony_ci### 全局自定义构建函数
48e41f4b71Sopenharmony_ci
49e41f4b71Sopenharmony_ci定义的语法:
50e41f4b71Sopenharmony_ci
51e41f4b71Sopenharmony_ci```ts
52e41f4b71Sopenharmony_ci@Builder function MyGlobalBuilderFunction() { ... }
53e41f4b71Sopenharmony_ci```
54e41f4b71Sopenharmony_ci
55e41f4b71Sopenharmony_ci使用方法:
56e41f4b71Sopenharmony_ci
57e41f4b71Sopenharmony_ci```ts
58e41f4b71Sopenharmony_ciMyGlobalBuilderFunction()
59e41f4b71Sopenharmony_ci```
60e41f4b71Sopenharmony_ci
61e41f4b71Sopenharmony_ci- 如果不涉及组件状态变化,建议使用全局的自定义构建方法。
62e41f4b71Sopenharmony_ci
63e41f4b71Sopenharmony_ci- 全局自定义构建函数允许在build方法和其他自定义构建函数中调用。
64e41f4b71Sopenharmony_ci
65e41f4b71Sopenharmony_ci
66e41f4b71Sopenharmony_ci## 参数传递规则
67e41f4b71Sopenharmony_ci
68e41f4b71Sopenharmony_ci自定义构建函数的参数传递有[按值传递](#按值传递参数)和[按引用传递](#按引用传递参数)两种,均需遵守以下规则:
69e41f4b71Sopenharmony_ci
70e41f4b71Sopenharmony_ci- 参数的类型必须与参数声明的类型一致,不允许undefined、null和返回undefined、null的表达式。
71e41f4b71Sopenharmony_ci
72e41f4b71Sopenharmony_ci- 在@Builder修饰的函数内部,不允许改变参数值。
73e41f4b71Sopenharmony_ci
74e41f4b71Sopenharmony_ci- \@Builder内UI语法遵循[UI语法规则](arkts-create-custom-components.md#build函数)。
75e41f4b71Sopenharmony_ci
76e41f4b71Sopenharmony_ci- 只有传入一个参数,且参数需要直接传入对象字面量才会按引用传递该参数,其余传递方式均为按值传递。
77e41f4b71Sopenharmony_ci
78e41f4b71Sopenharmony_ci
79e41f4b71Sopenharmony_ci### 按引用传递参数
80e41f4b71Sopenharmony_ci
81e41f4b71Sopenharmony_ci按引用传递参数时,传递的参数可为状态变量,且状态变量的改变会引起\@Builder方法内的UI刷新。
82e41f4b71Sopenharmony_ci
83e41f4b71Sopenharmony_ci```ts
84e41f4b71Sopenharmony_ciclass Tmp {
85e41f4b71Sopenharmony_ci  paramA1: string = ''
86e41f4b71Sopenharmony_ci}
87e41f4b71Sopenharmony_ci
88e41f4b71Sopenharmony_ci@Builder function overBuilder(params: Tmp) {
89e41f4b71Sopenharmony_ci  Row() {
90e41f4b71Sopenharmony_ci    Text(`UseStateVarByReference: ${params.paramA1} `)
91e41f4b71Sopenharmony_ci  }
92e41f4b71Sopenharmony_ci}
93e41f4b71Sopenharmony_ci@Entry
94e41f4b71Sopenharmony_ci@Component
95e41f4b71Sopenharmony_cistruct Parent {
96e41f4b71Sopenharmony_ci  @State label: string = 'Hello';
97e41f4b71Sopenharmony_ci  build() {
98e41f4b71Sopenharmony_ci    Column() {
99e41f4b71Sopenharmony_ci      // Pass the this.label reference to the overBuilder component when the overBuilder component is called in the Parent component.
100e41f4b71Sopenharmony_ci      overBuilder({ paramA1: this.label })
101e41f4b71Sopenharmony_ci      Button('Click me').onClick(() => {
102e41f4b71Sopenharmony_ci        // After Click me is clicked, the UI text changes from Hello to ArkUI.
103e41f4b71Sopenharmony_ci        this.label = 'ArkUI';
104e41f4b71Sopenharmony_ci      })
105e41f4b71Sopenharmony_ci    }
106e41f4b71Sopenharmony_ci  }
107e41f4b71Sopenharmony_ci}
108e41f4b71Sopenharmony_ci```
109e41f4b71Sopenharmony_ci
110e41f4b71Sopenharmony_ci按引用传递参数时,如果在\@Builder方法内调用自定义组件,ArkUI提供[$$](arkts-two-way-sync.md)作为按引用传递参数的范式。
111e41f4b71Sopenharmony_ci
112e41f4b71Sopenharmony_ci```ts
113e41f4b71Sopenharmony_ciclass Tmp {
114e41f4b71Sopenharmony_ci  paramA1: string = ''
115e41f4b71Sopenharmony_ci}
116e41f4b71Sopenharmony_ci
117e41f4b71Sopenharmony_ci@Builder function overBuilder($$: Tmp) {
118e41f4b71Sopenharmony_ci  Row() {
119e41f4b71Sopenharmony_ci    Column() {
120e41f4b71Sopenharmony_ci      Text(`overBuilder===${$$.paramA1}`)
121e41f4b71Sopenharmony_ci      HelloComponent({message: $$.paramA1})
122e41f4b71Sopenharmony_ci    }
123e41f4b71Sopenharmony_ci  }
124e41f4b71Sopenharmony_ci}
125e41f4b71Sopenharmony_ci
126e41f4b71Sopenharmony_ci@Component
127e41f4b71Sopenharmony_cistruct HelloComponent {
128e41f4b71Sopenharmony_ci  @Prop message: string;
129e41f4b71Sopenharmony_ci
130e41f4b71Sopenharmony_ci  build() {
131e41f4b71Sopenharmony_ci    Row() {
132e41f4b71Sopenharmony_ci      Text(`HelloComponent===${this.message}`)
133e41f4b71Sopenharmony_ci    }
134e41f4b71Sopenharmony_ci  }
135e41f4b71Sopenharmony_ci}
136e41f4b71Sopenharmony_ci
137e41f4b71Sopenharmony_ci@Entry
138e41f4b71Sopenharmony_ci@Component
139e41f4b71Sopenharmony_cistruct Parent {
140e41f4b71Sopenharmony_ci  @State label: string = 'Hello';
141e41f4b71Sopenharmony_ci  build() {
142e41f4b71Sopenharmony_ci    Column() {
143e41f4b71Sopenharmony_ci      // Pass the this.label reference to the overBuilder component when the overBuilder component is called in the Parent component.
144e41f4b71Sopenharmony_ci      overBuilder({paramA1: this.label})
145e41f4b71Sopenharmony_ci      Button('Click me').onClick(() => {
146e41f4b71Sopenharmony_ci        // After Click me is clicked, the UI text changes from Hello to ArkUI.
147e41f4b71Sopenharmony_ci        this.label = 'ArkUI';
148e41f4b71Sopenharmony_ci      })
149e41f4b71Sopenharmony_ci    }
150e41f4b71Sopenharmony_ci  }
151e41f4b71Sopenharmony_ci}
152e41f4b71Sopenharmony_ci```
153e41f4b71Sopenharmony_ci
154e41f4b71Sopenharmony_ci### 按值传递参数
155e41f4b71Sopenharmony_ci
156e41f4b71Sopenharmony_ci调用\@Builder装饰的函数默认按值传递。当传递的参数为状态变量时,状态变量的改变不会引起\@Builder方法内的UI刷新。所以当使用状态变量的时候,推荐使用[按引用传递](#按引用传递参数)。
157e41f4b71Sopenharmony_ci
158e41f4b71Sopenharmony_ci```ts
159e41f4b71Sopenharmony_ci@Builder function overBuilder(paramA1: string) {
160e41f4b71Sopenharmony_ci  Row() {
161e41f4b71Sopenharmony_ci    Text(`UseStateVarByValue: ${paramA1} `)
162e41f4b71Sopenharmony_ci  }
163e41f4b71Sopenharmony_ci}
164e41f4b71Sopenharmony_ci@Entry
165e41f4b71Sopenharmony_ci@Component
166e41f4b71Sopenharmony_cistruct Parent {
167e41f4b71Sopenharmony_ci  @State label: string = 'Hello';
168e41f4b71Sopenharmony_ci  build() {
169e41f4b71Sopenharmony_ci    Column() {
170e41f4b71Sopenharmony_ci      overBuilder(this.label)
171e41f4b71Sopenharmony_ci    }
172e41f4b71Sopenharmony_ci  }
173e41f4b71Sopenharmony_ci}
174e41f4b71Sopenharmony_ci```
175e41f4b71Sopenharmony_ci
176e41f4b71Sopenharmony_ci使用按值传递的方式,在@ComponentV2装饰器修饰的自定义组件里配合使用@ObservedV2和@Trace装饰器可以实现刷新UI功能。
177e41f4b71Sopenharmony_ci
178e41f4b71Sopenharmony_ci【正例】
179e41f4b71Sopenharmony_ci
180e41f4b71Sopenharmony_ci在@ComponentV2装饰中,只有使用@ObservedV2修饰的ParamTmp类和@Trace修饰的count属性才可以触发UI的刷新。
181e41f4b71Sopenharmony_ci
182e41f4b71Sopenharmony_ci```ts
183e41f4b71Sopenharmony_ci@ObservedV2
184e41f4b71Sopenharmony_ciclass ParamTmp {
185e41f4b71Sopenharmony_ci  @Trace count : number = 0;
186e41f4b71Sopenharmony_ci}
187e41f4b71Sopenharmony_ci
188e41f4b71Sopenharmony_ci@Builder
189e41f4b71Sopenharmony_cifunction renderText(param: ParamTmp) {
190e41f4b71Sopenharmony_ci  Column() {
191e41f4b71Sopenharmony_ci    Text(`param : ${param.count}`)
192e41f4b71Sopenharmony_ci      .fontSize(20)
193e41f4b71Sopenharmony_ci      .fontWeight(FontWeight.Bold)
194e41f4b71Sopenharmony_ci  }
195e41f4b71Sopenharmony_ci}
196e41f4b71Sopenharmony_ci
197e41f4b71Sopenharmony_ci@Builder
198e41f4b71Sopenharmony_cifunction renderMap(paramMap: Map<string,number>) {
199e41f4b71Sopenharmony_ci  Text(`paramMap : ${paramMap.get('name')}`)
200e41f4b71Sopenharmony_ci    .fontSize(20)
201e41f4b71Sopenharmony_ci    .fontWeight(FontWeight.Bold)
202e41f4b71Sopenharmony_ci}
203e41f4b71Sopenharmony_ci
204e41f4b71Sopenharmony_ci@Builder
205e41f4b71Sopenharmony_cifunction renderSet(paramSet: Set<number>) {
206e41f4b71Sopenharmony_ci  Text(`paramSet : ${paramSet.size}`)
207e41f4b71Sopenharmony_ci    .fontSize(20)
208e41f4b71Sopenharmony_ci    .fontWeight(FontWeight.Bold)
209e41f4b71Sopenharmony_ci}
210e41f4b71Sopenharmony_ci
211e41f4b71Sopenharmony_ci@Builder
212e41f4b71Sopenharmony_cifunction renderNumberArr(paramNumArr: number[]) {
213e41f4b71Sopenharmony_ci  Text(`paramNumArr : ${paramNumArr[0]}`)
214e41f4b71Sopenharmony_ci    .fontSize(20)
215e41f4b71Sopenharmony_ci    .fontWeight(FontWeight.Bold)
216e41f4b71Sopenharmony_ci}
217e41f4b71Sopenharmony_ci
218e41f4b71Sopenharmony_ci@Entry
219e41f4b71Sopenharmony_ci@ComponentV2
220e41f4b71Sopenharmony_cistruct PageBuilder {
221e41f4b71Sopenharmony_ci  @Local builderParams: ParamTmp = new ParamTmp();
222e41f4b71Sopenharmony_ci  @Local map_value: Map<string,number> = new Map();
223e41f4b71Sopenharmony_ci  @Local set_value: Set<number> = new Set([0]);
224e41f4b71Sopenharmony_ci  @Local numArr_value: number[] = [0];
225e41f4b71Sopenharmony_ci  private progressTimer: number = -1;
226e41f4b71Sopenharmony_ci
227e41f4b71Sopenharmony_ci  aboutToAppear(): void {
228e41f4b71Sopenharmony_ci    this.progressTimer = setInterval(() => {
229e41f4b71Sopenharmony_ci      if (this.builderParams.count < 100) {
230e41f4b71Sopenharmony_ci        this.builderParams.count += 5;
231e41f4b71Sopenharmony_ci        this.map_value.set('name', this.builderParams.count);
232e41f4b71Sopenharmony_ci        this.set_value.add(this.builderParams.count);
233e41f4b71Sopenharmony_ci        this.numArr_value[0] = this.builderParams.count;
234e41f4b71Sopenharmony_ci      } else {
235e41f4b71Sopenharmony_ci        clearInterval(this.progressTimer)
236e41f4b71Sopenharmony_ci      }
237e41f4b71Sopenharmony_ci    }, 500);
238e41f4b71Sopenharmony_ci  }
239e41f4b71Sopenharmony_ci
240e41f4b71Sopenharmony_ci  @Builder
241e41f4b71Sopenharmony_ci  localBuilder() {
242e41f4b71Sopenharmony_ci    Column() {
243e41f4b71Sopenharmony_ci      Text(`localBuilder : ${this.builderParams.count}`)
244e41f4b71Sopenharmony_ci        .fontSize(20)
245e41f4b71Sopenharmony_ci        .fontWeight(FontWeight.Bold)
246e41f4b71Sopenharmony_ci    }
247e41f4b71Sopenharmony_ci  }
248e41f4b71Sopenharmony_ci
249e41f4b71Sopenharmony_ci  build() {
250e41f4b71Sopenharmony_ci    Column() {
251e41f4b71Sopenharmony_ci      this.localBuilder()
252e41f4b71Sopenharmony_ci      Text(`builderParams :${this.builderParams.count}`)
253e41f4b71Sopenharmony_ci        .fontSize(20)
254e41f4b71Sopenharmony_ci        .fontWeight(FontWeight.Bold)
255e41f4b71Sopenharmony_ci      renderText(this.builderParams)
256e41f4b71Sopenharmony_ci      renderText({ count: this.builderParams.count })
257e41f4b71Sopenharmony_ci      renderMap(this.map_value)
258e41f4b71Sopenharmony_ci      renderSet(this.set_value)
259e41f4b71Sopenharmony_ci      renderNumberArr(this.numArr_value)
260e41f4b71Sopenharmony_ci    }
261e41f4b71Sopenharmony_ci    .width('100%')
262e41f4b71Sopenharmony_ci    .height('100%')
263e41f4b71Sopenharmony_ci  }
264e41f4b71Sopenharmony_ci}
265e41f4b71Sopenharmony_ci```
266e41f4b71Sopenharmony_ci
267e41f4b71Sopenharmony_ci【反例】
268e41f4b71Sopenharmony_ci
269e41f4b71Sopenharmony_ci在@ComponentV2装饰的自定义组件中,使用简单数据类型不可以触发UI的刷新。
270e41f4b71Sopenharmony_ci
271e41f4b71Sopenharmony_ci```ts
272e41f4b71Sopenharmony_ci@ObservedV2
273e41f4b71Sopenharmony_ciclass ParamTmp {
274e41f4b71Sopenharmony_ci  @Trace count : number = 0;
275e41f4b71Sopenharmony_ci}
276e41f4b71Sopenharmony_ci
277e41f4b71Sopenharmony_ci@Builder
278e41f4b71Sopenharmony_cifunction renderNumber(paramNum: number) {
279e41f4b71Sopenharmony_ci  Text(`paramNum : ${paramNum}`)
280e41f4b71Sopenharmony_ci    .fontSize(30)
281e41f4b71Sopenharmony_ci    .fontWeight(FontWeight.Bold)
282e41f4b71Sopenharmony_ci}
283e41f4b71Sopenharmony_ci
284e41f4b71Sopenharmony_ci@Entry
285e41f4b71Sopenharmony_ci@ComponentV2
286e41f4b71Sopenharmony_cistruct PageBuilder {
287e41f4b71Sopenharmony_ci  @Local class_value: ParamTmp = new ParamTmp();
288e41f4b71Sopenharmony_ci  // 此处使用简单数据类型不支持刷新UI的能力。
289e41f4b71Sopenharmony_ci  @Local num_value: number = 0;
290e41f4b71Sopenharmony_ci  private progressTimer: number = -1;
291e41f4b71Sopenharmony_ci
292e41f4b71Sopenharmony_ci  aboutToAppear(): void {
293e41f4b71Sopenharmony_ci    this.progressTimer = setInterval(() => {
294e41f4b71Sopenharmony_ci      if (this.class_value.count < 100) {
295e41f4b71Sopenharmony_ci        this.class_value.count += 5;
296e41f4b71Sopenharmony_ci        this.num_value += 5;
297e41f4b71Sopenharmony_ci      } else {
298e41f4b71Sopenharmony_ci        clearInterval(this.progressTimer)
299e41f4b71Sopenharmony_ci      }
300e41f4b71Sopenharmony_ci    }, 500);
301e41f4b71Sopenharmony_ci  }
302e41f4b71Sopenharmony_ci
303e41f4b71Sopenharmony_ci  build() {
304e41f4b71Sopenharmony_ci    Column() {
305e41f4b71Sopenharmony_ci      renderNumber(this.num_value)
306e41f4b71Sopenharmony_ci    }
307e41f4b71Sopenharmony_ci    .width('100%')
308e41f4b71Sopenharmony_ci    .height('100%')
309e41f4b71Sopenharmony_ci    .padding(50)
310e41f4b71Sopenharmony_ci  }
311e41f4b71Sopenharmony_ci}
312e41f4b71Sopenharmony_ci```
313e41f4b71Sopenharmony_ci
314e41f4b71Sopenharmony_ci## 使用场景
315e41f4b71Sopenharmony_ci
316e41f4b71Sopenharmony_ci### 自定义组件内使用自定义构建函数
317e41f4b71Sopenharmony_ci
318e41f4b71Sopenharmony_ci创建私有的\@Builder方法,在Column里面使用this.builder()方式调用,通过aboutToAppear生命周期函数和按钮的点击事件改变builder_value的内容,实现动态渲染UI。
319e41f4b71Sopenharmony_ci
320e41f4b71Sopenharmony_ci```ts
321e41f4b71Sopenharmony_ci@Entry
322e41f4b71Sopenharmony_ci@Component
323e41f4b71Sopenharmony_cistruct PrivateBuilder {
324e41f4b71Sopenharmony_ci  @State builder_value: string = 'Hello';
325e41f4b71Sopenharmony_ci
326e41f4b71Sopenharmony_ci  @Builder builder() {
327e41f4b71Sopenharmony_ci    Column(){
328e41f4b71Sopenharmony_ci      Text(this.builder_value)
329e41f4b71Sopenharmony_ci        .fontSize(30)
330e41f4b71Sopenharmony_ci        .fontWeight(FontWeight.Bold)
331e41f4b71Sopenharmony_ci    }
332e41f4b71Sopenharmony_ci  }
333e41f4b71Sopenharmony_ci
334e41f4b71Sopenharmony_ci  aboutToAppear(): void {
335e41f4b71Sopenharmony_ci    setTimeout(() => {
336e41f4b71Sopenharmony_ci      this.builder_value = 'Hello World';
337e41f4b71Sopenharmony_ci    },3000)
338e41f4b71Sopenharmony_ci  }
339e41f4b71Sopenharmony_ci
340e41f4b71Sopenharmony_ci  build() {
341e41f4b71Sopenharmony_ci    Row() {
342e41f4b71Sopenharmony_ci      Column() {
343e41f4b71Sopenharmony_ci        Text(this.builder_value)
344e41f4b71Sopenharmony_ci          .fontSize(30)
345e41f4b71Sopenharmony_ci          .fontWeight(FontWeight.Bold)
346e41f4b71Sopenharmony_ci        this.builder()
347e41f4b71Sopenharmony_ci        Button('点击改变builder_value内容')
348e41f4b71Sopenharmony_ci          .onClick(() => {
349e41f4b71Sopenharmony_ci            this.builder_value ='builder_value被点击了'
350e41f4b71Sopenharmony_ci          })
351e41f4b71Sopenharmony_ci      }
352e41f4b71Sopenharmony_ci    }
353e41f4b71Sopenharmony_ci  }
354e41f4b71Sopenharmony_ci}
355e41f4b71Sopenharmony_ci```
356e41f4b71Sopenharmony_ci
357e41f4b71Sopenharmony_ci### 使用全局自定义构建函数
358e41f4b71Sopenharmony_ci
359e41f4b71Sopenharmony_ci创建全局的\@Builder方法,在Column里面使用overBuilder()方式调用,通过以对象字面量的形式传递参数,无论是简单类型还是复杂类型,值的改变都会引起UI界面的刷新。
360e41f4b71Sopenharmony_ci
361e41f4b71Sopenharmony_ci```ts
362e41f4b71Sopenharmony_ciclass ChildTmp {
363e41f4b71Sopenharmony_ci  val: number = 1;
364e41f4b71Sopenharmony_ci}
365e41f4b71Sopenharmony_ci
366e41f4b71Sopenharmony_ciclass Tmp {
367e41f4b71Sopenharmony_ci  str_value: string = 'Hello';
368e41f4b71Sopenharmony_ci  num_value: number = 0;
369e41f4b71Sopenharmony_ci  tmp_value: ChildTmp = new ChildTmp();
370e41f4b71Sopenharmony_ci  arrayTmp_value: Array<ChildTmp> = [];
371e41f4b71Sopenharmony_ci}
372e41f4b71Sopenharmony_ci
373e41f4b71Sopenharmony_ci@Builder function overBuilder(param: Tmp) {
374e41f4b71Sopenharmony_ci  Column() {
375e41f4b71Sopenharmony_ci    Text(`str_value: ${param.str_value}`)
376e41f4b71Sopenharmony_ci    Text(`num_value: ${param.num_value}`)
377e41f4b71Sopenharmony_ci    Text(`tmp_value: ${param.tmp_value.val}`)
378e41f4b71Sopenharmony_ci    ForEach(param.arrayTmp_value, (item: ChildTmp) => {
379e41f4b71Sopenharmony_ci      Text(`arrayTmp_value: ${item.val}`)
380e41f4b71Sopenharmony_ci    }, (item: ChildTmp) => JSON.stringify(item))
381e41f4b71Sopenharmony_ci  }
382e41f4b71Sopenharmony_ci}
383e41f4b71Sopenharmony_ci
384e41f4b71Sopenharmony_ci@Entry
385e41f4b71Sopenharmony_ci@Component
386e41f4b71Sopenharmony_cistruct Parent {
387e41f4b71Sopenharmony_ci  @State objParam: Tmp = new Tmp();
388e41f4b71Sopenharmony_ci  build() {
389e41f4b71Sopenharmony_ci    Column() {
390e41f4b71Sopenharmony_ci      Text('通过调用@Builder渲染UI界面')
391e41f4b71Sopenharmony_ci        .fontSize(20)
392e41f4b71Sopenharmony_ci      overBuilder({str_value: this.objParam.str_value, num_value: this.objParam.num_value, tmp_value: this.objParam.tmp_value, arrayTmp_value: this.objParam.arrayTmp_value})
393e41f4b71Sopenharmony_ci      Line()
394e41f4b71Sopenharmony_ci        .width('100%')
395e41f4b71Sopenharmony_ci        .height(10)
396e41f4b71Sopenharmony_ci        .backgroundColor('#000000').margin(10)
397e41f4b71Sopenharmony_ci      Button('点击改变参数值').onClick(() => {
398e41f4b71Sopenharmony_ci        this.objParam.str_value = 'Hello World';
399e41f4b71Sopenharmony_ci        this.objParam.num_value = 1;
400e41f4b71Sopenharmony_ci        this.objParam.tmp_value.val = 8;
401e41f4b71Sopenharmony_ci        const child_value: ChildTmp = {
402e41f4b71Sopenharmony_ci          val: 2
403e41f4b71Sopenharmony_ci        }
404e41f4b71Sopenharmony_ci        this.objParam.arrayTmp_value.push(child_value)
405e41f4b71Sopenharmony_ci      })
406e41f4b71Sopenharmony_ci    }
407e41f4b71Sopenharmony_ci  }
408e41f4b71Sopenharmony_ci}
409e41f4b71Sopenharmony_ci```
410e41f4b71Sopenharmony_ci
411e41f4b71Sopenharmony_ci### 修改装饰器修饰的变量触发UI刷新
412e41f4b71Sopenharmony_ci
413e41f4b71Sopenharmony_ci此种方式是使用了装饰器的特性,监听值的改变触发UI刷新,不通过\@Builder传递参数。
414e41f4b71Sopenharmony_ci
415e41f4b71Sopenharmony_ci```ts
416e41f4b71Sopenharmony_ciclass Tmp {
417e41f4b71Sopenharmony_ci  str_value: string = 'Hello';
418e41f4b71Sopenharmony_ci}
419e41f4b71Sopenharmony_ci
420e41f4b71Sopenharmony_ci@Entry
421e41f4b71Sopenharmony_ci@Component
422e41f4b71Sopenharmony_cistruct Parent {
423e41f4b71Sopenharmony_ci  @State objParam: Tmp = new Tmp();
424e41f4b71Sopenharmony_ci  @State label: string = 'World';
425e41f4b71Sopenharmony_ci
426e41f4b71Sopenharmony_ci  @Builder privateBuilder() {
427e41f4b71Sopenharmony_ci    Column() {
428e41f4b71Sopenharmony_ci      Text(`wrapBuilder str_value: ${this.objParam.str_value}`)
429e41f4b71Sopenharmony_ci      Text(`wrapBuilder num: ${this.label}`)
430e41f4b71Sopenharmony_ci    }
431e41f4b71Sopenharmony_ci  }
432e41f4b71Sopenharmony_ci
433e41f4b71Sopenharmony_ci  build() {
434e41f4b71Sopenharmony_ci    Column() {
435e41f4b71Sopenharmony_ci      Text('通过调用@Builder渲染UI界面')
436e41f4b71Sopenharmony_ci        .fontSize(20)
437e41f4b71Sopenharmony_ci      this.privateBuilder()
438e41f4b71Sopenharmony_ci      Line()
439e41f4b71Sopenharmony_ci        .width('100%')
440e41f4b71Sopenharmony_ci        .height(10)
441e41f4b71Sopenharmony_ci        .backgroundColor('#000000').margin(10)
442e41f4b71Sopenharmony_ci      Button('点击改变参数值').onClick(() => {
443e41f4b71Sopenharmony_ci        this.objParam.str_value = 'str_value Hello World';
444e41f4b71Sopenharmony_ci        this.label = 'label Hello World'
445e41f4b71Sopenharmony_ci      })
446e41f4b71Sopenharmony_ci    }
447e41f4b71Sopenharmony_ci  }
448e41f4b71Sopenharmony_ci}
449e41f4b71Sopenharmony_ci```
450e41f4b71Sopenharmony_ci
451e41f4b71Sopenharmony_ci### 使用全局和局部的@Builder传入customBuilder类型
452e41f4b71Sopenharmony_ci
453e41f4b71Sopenharmony_ci```ts
454e41f4b71Sopenharmony_ci@Builder
455e41f4b71Sopenharmony_cifunction overBuilder() {
456e41f4b71Sopenharmony_ci  Row() {
457e41f4b71Sopenharmony_ci    Text('全局 Builder')
458e41f4b71Sopenharmony_ci      .fontSize(30)
459e41f4b71Sopenharmony_ci      .fontWeight(FontWeight.Bold)
460e41f4b71Sopenharmony_ci  }
461e41f4b71Sopenharmony_ci}
462e41f4b71Sopenharmony_ci
463e41f4b71Sopenharmony_ci@Entry
464e41f4b71Sopenharmony_ci@Component
465e41f4b71Sopenharmony_cistruct customBuilderDemo {
466e41f4b71Sopenharmony_ci  @State arr: number[] = [0, 1, 2, 3, 4];
467e41f4b71Sopenharmony_ci
468e41f4b71Sopenharmony_ci  @Builder privateBuilder() {
469e41f4b71Sopenharmony_ci    Row() {
470e41f4b71Sopenharmony_ci      Text('局部 Builder')
471e41f4b71Sopenharmony_ci        .fontSize(30)
472e41f4b71Sopenharmony_ci        .fontWeight(FontWeight.Bold)
473e41f4b71Sopenharmony_ci    }
474e41f4b71Sopenharmony_ci  }
475e41f4b71Sopenharmony_ci
476e41f4b71Sopenharmony_ci  build() {
477e41f4b71Sopenharmony_ci    Column() {
478e41f4b71Sopenharmony_ci      List({ space: 10 }) {
479e41f4b71Sopenharmony_ci        ForEach(this.arr, (item: number) => {
480e41f4b71Sopenharmony_ci          ListItem(){
481e41f4b71Sopenharmony_ci            Text(`${item}`)
482e41f4b71Sopenharmony_ci              .width('100%')
483e41f4b71Sopenharmony_ci              .height(100)
484e41f4b71Sopenharmony_ci              .fontSize(16)
485e41f4b71Sopenharmony_ci              .textAlign(TextAlign.Center)
486e41f4b71Sopenharmony_ci              .borderRadius(10)
487e41f4b71Sopenharmony_ci              .backgroundColor(0xFFFFFF)
488e41f4b71Sopenharmony_ci          }
489e41f4b71Sopenharmony_ci            .swipeAction({
490e41f4b71Sopenharmony_ci              start: {
491e41f4b71Sopenharmony_ci                builder: overBuilder()
492e41f4b71Sopenharmony_ci              },
493e41f4b71Sopenharmony_ci              end: {
494e41f4b71Sopenharmony_ci                builder: () => { this.privateBuilder() }
495e41f4b71Sopenharmony_ci              }
496e41f4b71Sopenharmony_ci            })
497e41f4b71Sopenharmony_ci        }, (item: string) => JSON.stringify(item))
498e41f4b71Sopenharmony_ci      }
499e41f4b71Sopenharmony_ci    }
500e41f4b71Sopenharmony_ci  }
501e41f4b71Sopenharmony_ci}
502e41f4b71Sopenharmony_ci```
503e41f4b71Sopenharmony_ci
504e41f4b71Sopenharmony_ci### 多层\@Builder方法嵌套使用
505e41f4b71Sopenharmony_ci
506e41f4b71Sopenharmony_ci在\@Builder方法内调用自定义组件或者其他\@Builder方法,ArkUI提供[$$](arkts-two-way-sync.md)作为按引用传递参数的范式。
507e41f4b71Sopenharmony_ci
508e41f4b71Sopenharmony_ci```ts
509e41f4b71Sopenharmony_ciclass Tmp {
510e41f4b71Sopenharmony_ci  paramA1: string = '';
511e41f4b71Sopenharmony_ci}
512e41f4b71Sopenharmony_ci
513e41f4b71Sopenharmony_ci@Builder function parentBuilder($$: Tmp) {
514e41f4b71Sopenharmony_ci  Row() {
515e41f4b71Sopenharmony_ci    Column() {
516e41f4b71Sopenharmony_ci      Text(`parentBuilder===${$$.paramA1}`)
517e41f4b71Sopenharmony_ci        .fontSize(30)
518e41f4b71Sopenharmony_ci        .fontWeight(FontWeight.Bold)
519e41f4b71Sopenharmony_ci      HelloComponent({message: $$.paramA1})
520e41f4b71Sopenharmony_ci      childBuilder({paramA1: $$.paramA1})
521e41f4b71Sopenharmony_ci    }
522e41f4b71Sopenharmony_ci  }
523e41f4b71Sopenharmony_ci}
524e41f4b71Sopenharmony_ci
525e41f4b71Sopenharmony_ci@Component
526e41f4b71Sopenharmony_cistruct HelloComponent {
527e41f4b71Sopenharmony_ci  @Prop message: string = '';
528e41f4b71Sopenharmony_ci
529e41f4b71Sopenharmony_ci  build() {
530e41f4b71Sopenharmony_ci    Row() {
531e41f4b71Sopenharmony_ci      Text(`HelloComponent===${this.message}`)
532e41f4b71Sopenharmony_ci        .fontSize(30)
533e41f4b71Sopenharmony_ci        .fontWeight(FontWeight.Bold)
534e41f4b71Sopenharmony_ci    }
535e41f4b71Sopenharmony_ci  }
536e41f4b71Sopenharmony_ci}
537e41f4b71Sopenharmony_ci
538e41f4b71Sopenharmony_ci@Builder
539e41f4b71Sopenharmony_cifunction childBuilder($$: Tmp) {
540e41f4b71Sopenharmony_ci  Row() {
541e41f4b71Sopenharmony_ci    Column() {
542e41f4b71Sopenharmony_ci      Text(`childBuilder===${$$.paramA1}`)
543e41f4b71Sopenharmony_ci        .fontSize(30)
544e41f4b71Sopenharmony_ci        .fontWeight(FontWeight.Bold)
545e41f4b71Sopenharmony_ci      HelloChildComponent({message: $$.paramA1})
546e41f4b71Sopenharmony_ci      grandsonBuilder({paramA1: $$.paramA1})
547e41f4b71Sopenharmony_ci    }
548e41f4b71Sopenharmony_ci  }
549e41f4b71Sopenharmony_ci}
550e41f4b71Sopenharmony_ci
551e41f4b71Sopenharmony_ci@Component
552e41f4b71Sopenharmony_cistruct HelloChildComponent {
553e41f4b71Sopenharmony_ci  @State message: string = '';
554e41f4b71Sopenharmony_ci  build() {
555e41f4b71Sopenharmony_ci    Row() {
556e41f4b71Sopenharmony_ci      Text(`HelloChildComponent===${this.message}`)
557e41f4b71Sopenharmony_ci        .fontSize(30)
558e41f4b71Sopenharmony_ci        .fontWeight(FontWeight.Bold)
559e41f4b71Sopenharmony_ci    }
560e41f4b71Sopenharmony_ci  }
561e41f4b71Sopenharmony_ci}
562e41f4b71Sopenharmony_ci
563e41f4b71Sopenharmony_ci@Builder function grandsonBuilder($$: Tmp) {
564e41f4b71Sopenharmony_ci  Row() {
565e41f4b71Sopenharmony_ci    Column() {
566e41f4b71Sopenharmony_ci      Text(`grandsonBuilder===${$$.paramA1}`)
567e41f4b71Sopenharmony_ci        .fontSize(30)
568e41f4b71Sopenharmony_ci        .fontWeight(FontWeight.Bold)
569e41f4b71Sopenharmony_ci      HelloGrandsonComponent({message: $$.paramA1})
570e41f4b71Sopenharmony_ci    }
571e41f4b71Sopenharmony_ci  }
572e41f4b71Sopenharmony_ci}
573e41f4b71Sopenharmony_ci
574e41f4b71Sopenharmony_ci@Component
575e41f4b71Sopenharmony_cistruct HelloGrandsonComponent {
576e41f4b71Sopenharmony_ci  @Prop message: string;
577e41f4b71Sopenharmony_ci  build() {
578e41f4b71Sopenharmony_ci    Row() {
579e41f4b71Sopenharmony_ci      Text(`HelloGrandsonComponent===${this.message}`)
580e41f4b71Sopenharmony_ci        .fontSize(30)
581e41f4b71Sopenharmony_ci        .fontWeight(FontWeight.Bold)
582e41f4b71Sopenharmony_ci    }
583e41f4b71Sopenharmony_ci  }
584e41f4b71Sopenharmony_ci}
585e41f4b71Sopenharmony_ci
586e41f4b71Sopenharmony_ci@Entry
587e41f4b71Sopenharmony_ci@Component
588e41f4b71Sopenharmony_cistruct Parent {
589e41f4b71Sopenharmony_ci  @State label: string = 'Hello';
590e41f4b71Sopenharmony_ci  build() {
591e41f4b71Sopenharmony_ci    Column() {
592e41f4b71Sopenharmony_ci      parentBuilder({paramA1: this.label})
593e41f4b71Sopenharmony_ci      Button('Click me').onClick(() => {
594e41f4b71Sopenharmony_ci        this.label = 'ArkUI';
595e41f4b71Sopenharmony_ci      })
596e41f4b71Sopenharmony_ci    }
597e41f4b71Sopenharmony_ci  }
598e41f4b71Sopenharmony_ci}
599e41f4b71Sopenharmony_ci```
600e41f4b71Sopenharmony_ci
601e41f4b71Sopenharmony_ci### \@Builder函数联合V2装饰器使用
602e41f4b71Sopenharmony_ci
603e41f4b71Sopenharmony_ci使用全局@Builder和局部@Builder在@ComponentV2修饰的自定义组件中调用,修改相关变量触发UI刷新。
604e41f4b71Sopenharmony_ci
605e41f4b71Sopenharmony_ci```ts
606e41f4b71Sopenharmony_ci@ObservedV2
607e41f4b71Sopenharmony_ciclass Info {
608e41f4b71Sopenharmony_ci  @Trace name: string = '';
609e41f4b71Sopenharmony_ci  @Trace age: number = 0;
610e41f4b71Sopenharmony_ci}
611e41f4b71Sopenharmony_ci
612e41f4b71Sopenharmony_ci@Builder
613e41f4b71Sopenharmony_cifunction overBuilder(param: Info) {
614e41f4b71Sopenharmony_ci  Column() {
615e41f4b71Sopenharmony_ci    Text(`全局@Builder name :${param.name}`)
616e41f4b71Sopenharmony_ci      .fontSize(30)
617e41f4b71Sopenharmony_ci      .fontWeight(FontWeight.Bold)
618e41f4b71Sopenharmony_ci    Text(`全局@Builder age :${param.age}`)
619e41f4b71Sopenharmony_ci      .fontSize(30)
620e41f4b71Sopenharmony_ci      .fontWeight(FontWeight.Bold)
621e41f4b71Sopenharmony_ci  }
622e41f4b71Sopenharmony_ci}
623e41f4b71Sopenharmony_ci
624e41f4b71Sopenharmony_ci@ComponentV2
625e41f4b71Sopenharmony_cistruct ChildPage {
626e41f4b71Sopenharmony_ci  @Require @Param childInfo: Info;
627e41f4b71Sopenharmony_ci  build() {
628e41f4b71Sopenharmony_ci    overBuilder({name: this.childInfo.name, age: this.childInfo.age})
629e41f4b71Sopenharmony_ci  }
630e41f4b71Sopenharmony_ci}
631e41f4b71Sopenharmony_ci
632e41f4b71Sopenharmony_ci@Entry
633e41f4b71Sopenharmony_ci@ComponentV2
634e41f4b71Sopenharmony_cistruct ParentPage {
635e41f4b71Sopenharmony_ci  info1: Info = { name: "Tom", age: 25 };
636e41f4b71Sopenharmony_ci  @Local info2: Info = { name: "Tom", age: 25 };
637e41f4b71Sopenharmony_ci
638e41f4b71Sopenharmony_ci  @Builder
639e41f4b71Sopenharmony_ci  privateBuilder() {
640e41f4b71Sopenharmony_ci    Column() {
641e41f4b71Sopenharmony_ci      Text(`局部@Builder name :${this.info1.name}`)
642e41f4b71Sopenharmony_ci        .fontSize(30)
643e41f4b71Sopenharmony_ci        .fontWeight(FontWeight.Bold)
644e41f4b71Sopenharmony_ci      Text(`局部@Builder age :${this.info1.age}`)
645e41f4b71Sopenharmony_ci        .fontSize(30)
646e41f4b71Sopenharmony_ci        .fontWeight(FontWeight.Bold)
647e41f4b71Sopenharmony_ci    }
648e41f4b71Sopenharmony_ci  }
649e41f4b71Sopenharmony_ci
650e41f4b71Sopenharmony_ci  build() {
651e41f4b71Sopenharmony_ci    Column() {
652e41f4b71Sopenharmony_ci      Text(`info1: ${this.info1.name}  ${this.info1.age}`) // Text1
653e41f4b71Sopenharmony_ci        .fontSize(30)
654e41f4b71Sopenharmony_ci        .fontWeight(FontWeight.Bold)
655e41f4b71Sopenharmony_ci      this.privateBuilder() // 调用局部@Builder
656e41f4b71Sopenharmony_ci      Line()
657e41f4b71Sopenharmony_ci        .width('100%')
658e41f4b71Sopenharmony_ci        .height(10)
659e41f4b71Sopenharmony_ci        .backgroundColor('#000000').margin(10)
660e41f4b71Sopenharmony_ci      Text(`info2: ${this.info2.name}  ${this.info2.age}`) // Text2
661e41f4b71Sopenharmony_ci        .fontSize(30)
662e41f4b71Sopenharmony_ci        .fontWeight(FontWeight.Bold)
663e41f4b71Sopenharmony_ci      overBuilder({ name: this.info2.name, age: this.info2.age}) // 调用全局@Builder
664e41f4b71Sopenharmony_ci      Line()
665e41f4b71Sopenharmony_ci        .width('100%')
666e41f4b71Sopenharmony_ci        .height(10)
667e41f4b71Sopenharmony_ci        .backgroundColor('#000000').margin(10)
668e41f4b71Sopenharmony_ci      Text(`info1: ${this.info1.name}  ${this.info1.age}`) // Text1
669e41f4b71Sopenharmony_ci        .fontSize(30)
670e41f4b71Sopenharmony_ci        .fontWeight(FontWeight.Bold)
671e41f4b71Sopenharmony_ci      ChildPage({ childInfo: this.info1}) // 调用自定义组件
672e41f4b71Sopenharmony_ci      Line()
673e41f4b71Sopenharmony_ci        .width('100%')
674e41f4b71Sopenharmony_ci        .height(10)
675e41f4b71Sopenharmony_ci        .backgroundColor('#000000').margin(10)
676e41f4b71Sopenharmony_ci      Text(`info2: ${this.info2.name}  ${this.info2.age}`) // Text2
677e41f4b71Sopenharmony_ci        .fontSize(30)
678e41f4b71Sopenharmony_ci        .fontWeight(FontWeight.Bold)
679e41f4b71Sopenharmony_ci      ChildPage({ childInfo: this.info2}) // 调用自定义组件
680e41f4b71Sopenharmony_ci      Line()
681e41f4b71Sopenharmony_ci        .width('100%')
682e41f4b71Sopenharmony_ci        .height(10)
683e41f4b71Sopenharmony_ci        .backgroundColor('#000000').margin(10)
684e41f4b71Sopenharmony_ci      Button("change info1&info2")
685e41f4b71Sopenharmony_ci        .onClick(() => {
686e41f4b71Sopenharmony_ci          this.info1 = { name: "Cat", age: 18} // Text1不会刷新,原因是没有装饰器修饰监听不到值的改变。
687e41f4b71Sopenharmony_ci          this.info2 = { name: "Cat", age: 18} // Text2会刷新,原因是有装饰器修饰,可以监听到值的改变。
688e41f4b71Sopenharmony_ci        })
689e41f4b71Sopenharmony_ci    }
690e41f4b71Sopenharmony_ci  }
691e41f4b71Sopenharmony_ci}
692e41f4b71Sopenharmony_ci```
693e41f4b71Sopenharmony_ci
694e41f4b71Sopenharmony_ci## 常见问题
695e41f4b71Sopenharmony_ci
696e41f4b71Sopenharmony_ci### \@Builder存在两个或者两个以上参数
697e41f4b71Sopenharmony_ci
698e41f4b71Sopenharmony_ci当参数存在两个或者两个以上的时候,就算通过对象字面量的形式传递,值的改变也不会引起UI刷新。
699e41f4b71Sopenharmony_ci
700e41f4b71Sopenharmony_ci【反例】
701e41f4b71Sopenharmony_ci
702e41f4b71Sopenharmony_ci```ts
703e41f4b71Sopenharmony_ciclass GlobalTmp {
704e41f4b71Sopenharmony_ci  str_value: string = 'Hello';
705e41f4b71Sopenharmony_ci}
706e41f4b71Sopenharmony_ci
707e41f4b71Sopenharmony_ci@Builder function overBuilder(param: GlobalTmp, num: number) {
708e41f4b71Sopenharmony_ci  Column() {
709e41f4b71Sopenharmony_ci    Text(`str_value: ${param.str_value}`)
710e41f4b71Sopenharmony_ci    Text(`num: ${num}`)
711e41f4b71Sopenharmony_ci  }
712e41f4b71Sopenharmony_ci}
713e41f4b71Sopenharmony_ci
714e41f4b71Sopenharmony_ci@Entry
715e41f4b71Sopenharmony_ci@Component
716e41f4b71Sopenharmony_cistruct Parent {
717e41f4b71Sopenharmony_ci  @State objParam: GlobalTmp = new GlobalTmp();
718e41f4b71Sopenharmony_ci  @State num: number = 0;
719e41f4b71Sopenharmony_ci  build() {
720e41f4b71Sopenharmony_ci    Column() {
721e41f4b71Sopenharmony_ci      Text('通过调用@Builder渲染UI界面')
722e41f4b71Sopenharmony_ci        .fontSize(20)
723e41f4b71Sopenharmony_ci      overBuilder({str_value: this.objParam.str_value}, this.num) // 此处出现问题,使用了两个参数。
724e41f4b71Sopenharmony_ci      Line()
725e41f4b71Sopenharmony_ci        .width('100%')
726e41f4b71Sopenharmony_ci        .height(10)
727e41f4b71Sopenharmony_ci        .backgroundColor('#000000').margin(10)
728e41f4b71Sopenharmony_ci      Button('点击改变参数值').onClick(() => {
729e41f4b71Sopenharmony_ci        this.objParam.str_value = 'Hello World';
730e41f4b71Sopenharmony_ci        this.num = 1;
731e41f4b71Sopenharmony_ci      })
732e41f4b71Sopenharmony_ci    }
733e41f4b71Sopenharmony_ci  }
734e41f4b71Sopenharmony_ci}
735e41f4b71Sopenharmony_ci```
736e41f4b71Sopenharmony_ci
737e41f4b71Sopenharmony_ci【反例】
738e41f4b71Sopenharmony_ci
739e41f4b71Sopenharmony_ci```ts
740e41f4b71Sopenharmony_ciclass GlobalTmp {
741e41f4b71Sopenharmony_ci  str_value: string = 'Hello';
742e41f4b71Sopenharmony_ci}
743e41f4b71Sopenharmony_ciclass SecondTmp {
744e41f4b71Sopenharmony_ci  num_value: number = 0;
745e41f4b71Sopenharmony_ci}
746e41f4b71Sopenharmony_ci@Builder function overBuilder(param: GlobalTmp, num: SecondTmp) {
747e41f4b71Sopenharmony_ci  Column() {
748e41f4b71Sopenharmony_ci    Text(`str_value: ${param.str_value}`)
749e41f4b71Sopenharmony_ci    Text(`num: ${num.num_value}`)
750e41f4b71Sopenharmony_ci  }
751e41f4b71Sopenharmony_ci}
752e41f4b71Sopenharmony_ci
753e41f4b71Sopenharmony_ci@Entry
754e41f4b71Sopenharmony_ci@Component
755e41f4b71Sopenharmony_cistruct Parent {
756e41f4b71Sopenharmony_ci  @State strParam: GlobalTmp = new GlobalTmp();
757e41f4b71Sopenharmony_ci  @State numParam: SecondTmp = new SecondTmp();
758e41f4b71Sopenharmony_ci  build() {
759e41f4b71Sopenharmony_ci    Column() {
760e41f4b71Sopenharmony_ci      Text('通过调用@Builder渲染UI界面')
761e41f4b71Sopenharmony_ci        .fontSize(20)
762e41f4b71Sopenharmony_ci      overBuilder({str_value: this.strParam.str_value}, {num_value: this.numParam.num_value}) // 此处出现问题,使用了两个参数。
763e41f4b71Sopenharmony_ci      Line()
764e41f4b71Sopenharmony_ci        .width('100%')
765e41f4b71Sopenharmony_ci        .height(10)
766e41f4b71Sopenharmony_ci        .backgroundColor('#000000').margin(10)
767e41f4b71Sopenharmony_ci      Button('点击改变参数值').onClick(() => {
768e41f4b71Sopenharmony_ci        this.strParam.str_value = 'Hello World';
769e41f4b71Sopenharmony_ci        this.numParam.num_value = 1;
770e41f4b71Sopenharmony_ci      })
771e41f4b71Sopenharmony_ci    }
772e41f4b71Sopenharmony_ci  }
773e41f4b71Sopenharmony_ci}
774e41f4b71Sopenharmony_ci```
775e41f4b71Sopenharmony_ci
776e41f4b71Sopenharmony_ci\@Builder只接受一个参数,当传入一个参数的时候,通过对象字面量的形式传递,值的改变会引起UI的刷新。
777e41f4b71Sopenharmony_ci
778e41f4b71Sopenharmony_ci【正例】
779e41f4b71Sopenharmony_ci
780e41f4b71Sopenharmony_ci```ts
781e41f4b71Sopenharmony_ciclass GlobalTmp {
782e41f4b71Sopenharmony_ci  str_value: string = 'Hello';
783e41f4b71Sopenharmony_ci  num_value: number = 0;
784e41f4b71Sopenharmony_ci}
785e41f4b71Sopenharmony_ci@Builder function overBuilder(param: GlobalTmp) {
786e41f4b71Sopenharmony_ci  Column() {
787e41f4b71Sopenharmony_ci    Text(`str_value: ${param.str_value}`)
788e41f4b71Sopenharmony_ci    Text(`num: ${param.num_value}`)
789e41f4b71Sopenharmony_ci  }
790e41f4b71Sopenharmony_ci}
791e41f4b71Sopenharmony_ci
792e41f4b71Sopenharmony_ci@Entry
793e41f4b71Sopenharmony_ci@Component
794e41f4b71Sopenharmony_cistruct Parent {
795e41f4b71Sopenharmony_ci  @State objParam: GlobalTmp = new GlobalTmp();
796e41f4b71Sopenharmony_ci  build() {
797e41f4b71Sopenharmony_ci    Column() {
798e41f4b71Sopenharmony_ci      Text('通过调用@Builder渲染UI界面')
799e41f4b71Sopenharmony_ci        .fontSize(20)
800e41f4b71Sopenharmony_ci      overBuilder({str_value: this.objParam.str_value, num_value: this.objParam.num_value})
801e41f4b71Sopenharmony_ci      Line()
802e41f4b71Sopenharmony_ci        .width('100%')
803e41f4b71Sopenharmony_ci        .height(10)
804e41f4b71Sopenharmony_ci        .backgroundColor('#000000').margin(10)
805e41f4b71Sopenharmony_ci      Button('点击改变参数值').onClick(() => {
806e41f4b71Sopenharmony_ci        this.objParam.str_value = 'Hello World';
807e41f4b71Sopenharmony_ci        this.objParam.num_value = 1;
808e41f4b71Sopenharmony_ci      })
809e41f4b71Sopenharmony_ci    }
810e41f4b71Sopenharmony_ci  }
811e41f4b71Sopenharmony_ci}
812e41f4b71Sopenharmony_ci```
813e41f4b71Sopenharmony_ci
814e41f4b71Sopenharmony_ci### \@Builder函数里面使用的组件没有根节点包裹
815e41f4b71Sopenharmony_ci
816e41f4b71Sopenharmony_ci在\@Builder函数里使用if判断语句时,创建的组件没有被Column/Row(根节点)包裹,会出现组件创建不出来的情况。
817e41f4b71Sopenharmony_ci
818e41f4b71Sopenharmony_ci【反例】
819e41f4b71Sopenharmony_ci
820e41f4b71Sopenharmony_ci```ts
821e41f4b71Sopenharmony_ciconst showComponent: boolean = true;
822e41f4b71Sopenharmony_ci@Builder function OverlayNode() {
823e41f4b71Sopenharmony_ci  // 没有Column或者Row根节点导致Text组件没有创建
824e41f4b71Sopenharmony_ci  if (showComponent) {
825e41f4b71Sopenharmony_ci      Text("This is overlayNode Blue page")
826e41f4b71Sopenharmony_ci        .fontSize(20)
827e41f4b71Sopenharmony_ci        .fontColor(Color.Blue)
828e41f4b71Sopenharmony_ci        .height(100)
829e41f4b71Sopenharmony_ci        .textAlign(TextAlign.End)
830e41f4b71Sopenharmony_ci    } else {
831e41f4b71Sopenharmony_ci      Text("This is overlayNode Red page")
832e41f4b71Sopenharmony_ci        .fontSize(20)
833e41f4b71Sopenharmony_ci        .fontColor(Color.Red)
834e41f4b71Sopenharmony_ci    }
835e41f4b71Sopenharmony_ci}
836e41f4b71Sopenharmony_ci
837e41f4b71Sopenharmony_ci@Entry
838e41f4b71Sopenharmony_ci@Component
839e41f4b71Sopenharmony_cistruct OverlayExample {
840e41f4b71Sopenharmony_ci
841e41f4b71Sopenharmony_ci  build() {
842e41f4b71Sopenharmony_ci    RelativeContainer() {
843e41f4b71Sopenharmony_ci      Text('Hello World')
844e41f4b71Sopenharmony_ci        .overlay(OverlayNode(), { align: Alignment.Center})
845e41f4b71Sopenharmony_ci    }
846e41f4b71Sopenharmony_ci    .height('100%')
847e41f4b71Sopenharmony_ci    .width('100%')
848e41f4b71Sopenharmony_ci  }
849e41f4b71Sopenharmony_ci}
850e41f4b71Sopenharmony_ci```
851e41f4b71Sopenharmony_ci
852e41f4b71Sopenharmony_ci【正例】
853e41f4b71Sopenharmony_ci
854e41f4b71Sopenharmony_ci```ts
855e41f4b71Sopenharmony_ciconst showComponent: boolean = true;
856e41f4b71Sopenharmony_ci@Builder function OverlayNode() {
857e41f4b71Sopenharmony_ci  Column() {
858e41f4b71Sopenharmony_ci    if (showComponent) {
859e41f4b71Sopenharmony_ci      Text("This is overlayNode Blue page")
860e41f4b71Sopenharmony_ci        .fontSize(20)
861e41f4b71Sopenharmony_ci        .fontColor(Color.Blue)
862e41f4b71Sopenharmony_ci        .height(100)
863e41f4b71Sopenharmony_ci        .textAlign(TextAlign.End)
864e41f4b71Sopenharmony_ci    } else {
865e41f4b71Sopenharmony_ci      Text("This is overlayNode Red page")
866e41f4b71Sopenharmony_ci        .fontSize(20)
867e41f4b71Sopenharmony_ci        .fontColor(Color.Red)
868e41f4b71Sopenharmony_ci    }
869e41f4b71Sopenharmony_ci  }
870e41f4b71Sopenharmony_ci}
871e41f4b71Sopenharmony_ci
872e41f4b71Sopenharmony_ci@Entry
873e41f4b71Sopenharmony_ci@Component
874e41f4b71Sopenharmony_cistruct OverlayExample {
875e41f4b71Sopenharmony_ci
876e41f4b71Sopenharmony_ci  build() {
877e41f4b71Sopenharmony_ci    RelativeContainer() {
878e41f4b71Sopenharmony_ci      Text('Hello World')
879e41f4b71Sopenharmony_ci        .overlay(OverlayNode(), { align: Alignment.Center})
880e41f4b71Sopenharmony_ci    }
881e41f4b71Sopenharmony_ci    .height('100%')
882e41f4b71Sopenharmony_ci    .width('100%')
883e41f4b71Sopenharmony_ci  }
884e41f4b71Sopenharmony_ci}
885e41f4b71Sopenharmony_ci```