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