鸿蒙4.0开发笔记之ArkTS装饰器语法基础@Builder组件内自定义构建函数与@Styles自定义组件重用样式(十)

一、@Builder自定义构建函数

1、什么是自定义构建函数

ArkUI还提供了⼀种更轻量的UI元素复用机制 @Builder , @Builder 所装饰的函数遵循
build() 函数语法规则,开发者可以将重复使用的UI元素抽象成⼀个方法,在build方法里调用。

2、组件内定义构建函数

(1)定义语法:@Builder MyBuilder(...) {...}
(2)使用语法:this.MyBuilder(...) {...}
(3)语法要点:

  • 自定义构建函数可以在所属组件的 build方法和其他自定义构建函数中调用,但不允许在组件外调用。
  • 允许在自定义组件内定义⼀个或多个 @Builder方法,该方法被认为是该组件的私有、特殊类型的成员函数。
  • 在自定义函数体中,this指代当前所属组件,组件的状态变量可以在自定义构建函数内访问。建议通过this访问自定义组件的状态变量而不是参数传递。
  • 自定义组件不仅可以添加属性,还可以添加事件
    (4)参数传递规则
    4、参数传递规则
    自定义构建函数的参数传递有按值传递和按引用传递两种,均需遵守以下规则:

参数的类型必须与参数声明的类型一致,不允许undefined、null和返回undefined、null的表达式。
在自定义构建函数内部,不允许改变参数值。如果需要改变参数值,且同步回调用点,建议使用@Link。
@Builder内UI语法遵循官方文档:自定义组件语法规则

3、组件外定义构建函数

组件外定义构建函数的优点是方便多组件共同调用。定义时,需要加上function关键字。

//在组件外定义words构建函数
@Builder function words2(content:string){
   
   ...}
//使用组件外定义的构建函数:不能使用this或bind方法
words2(content)

4、@Builder装饰器练习

(1)练习任务
定义一个被@Builder修饰的构建函数,要求能够在同一行显示图标和文本。使用状态值刷新属性,点击时图标和文本发生相应的变化;刷新动作,再次点击后能够恢复原来的状态。

(2)练习代码

@Entry
@Component
struct Index {
   
   
  @State message: string = '@Builder \n 组件内构建函数'
  //设置状态变量,方便在选中诗词时能够作为标志位,默认未选中
  @State isChoose: boolean = false

  //创建组件内的构建函数:可以设定传递参数content
  @Builder words(content:string){
   
   
    Row(){
   
   
      Image(this.isChoose ? $r('app.media.icon') : $r('app.media.ic'))
        .width(35)
        .margin(15)
      //构建函数调用自己的形式参数时不需要使用this引用
      Text(content)
        .fontSize(25)
        .decoration({
   
   type:this.isChoose ? TextDecorationType.LineThrough 
<think> 我们正在讨论的是ArkTS中的@Builder装饰器,用于自定义构建函数。根据引用内容,我们可以总结如下: 1. @Builder装饰器用于创建自定义构建函数,可以将重复的UI结构抽象成一个方法。 2. @Builder装饰的函数遵循build()函数语法规则。 3. @Builder有两种类型:自定义组件内定义的私有@Builder(只能在组件内调用)和全局的@Builder(可以在整个应用内调用)。 4. 参数传递方式:默认按值传递,但为了在传递状态变量时能够触发UI刷新,推荐使用按引用传递(使用'$'符号)。 下面将详细介绍使用方法,包括基本使用、参数传递、在组件内定义和全局定义等。 ### 1. 基本使用方法 #### 1.1 组件内私有@Builder自定义组件内使用`@Builder`装饰一个函数,该函数可以在组件的build函数或其他自定义构建函数中调用。 ```typescript @Entry @Component struct MyComponent { @Builder myBuilderFunction() { // 在这里构建UI Column() { Text('Hello, Builder!') .fontSize(20) Button('Click me') .onClick(() => { // 点击事件 }) } } build() { Column() { // 调用自定义构建函数 this.myBuilderFunction() } } } ``` #### 1.2 全局@Builder组件外定义的@Builder函数是全局的,可以在任意组件中调用。 ```typescript // 全局自定义构建函数 @Builder function GlobalBuilder() { Row() { Text('Global Builder') .fontColor(Color.Blue) } } @Entry @Component struct MyComponent { build() { Column() { // 调用全局构建函数 GlobalBuilder() } } } ``` ### 2. 参数传递 #### 2.1 按值传递(默认) 默认情况下,@Builder函数的参数是按值传递的。这意味着当传递的状态变量发生变化时,不会触发@Builder函数内部的UI刷新。 ```typescript @Builder function ValueTransferBuilder(paramA: string) { Row() { Text(`参数值: ${paramA}`) } } @Entry @Component struct ParentComponent { @State message: string = '初始值' build() { Column() { // 按值传递,message的变化不会触发Builder内部更新 ValueTransferBuilder(this.message) Button('改变值').onClick(() => { this.message = '新值' }) } } } ``` 点击按钮后,虽然`message`状态改变了,但`ValueTransferBuilder`中显示的文本不会更新。 #### 2.2 按引用传递 为了能够响应状态变化,需要使用按引用传递,在参数名前加上`$`符号。 ```typescript @Builder function ReferenceTransferBuilder($paramA: string) { Row() { Text(`参数值: ${$paramA}`) // 当paramA变化时,这里会更新 } } @Entry @Component struct ParentComponent { @State message: string = '初始值' build() { Column() { // 按引用传递,message变化会触发Builder内部更新 ReferenceTransferBuilder($$this.message) Button('改变值').onClick(() => { this.message = '新值' }) } } } ``` 注意:在调用时,我们使用`$$`来传递状态变量的引用(在ArkTS中,按引用传递的语法是`$$变量名`)。这样,当状态变量`message`改变时,构建函数内部也会更新。 ### 3.@Builder中访问组件状态 在组件内@Builder函数中,可以直接通过`this`访问组件的状态变量。 ```typescript @Entry @Component struct MyComponent { @State count: number = 0 @Builder CounterBuilder() { // 直接使用this.count访问组件的状态变量 Button(`点击次数: ${this.count}`) .onClick(() => { this.count++ // 修改状态,会触发UI更新 }) } build() { Column() { this.CounterBuilder() } } } ``` ### 4. 组合使用多个@Builder 自定义构建函数可以相互调用,实现更复杂的UI复用。 ```typescript @Entry @Component struct MyComponent { @Builder HeaderBuilder(title: string) { Text(title) .fontSize(30) .fontWeight(FontWeight.Bold) } @Builder FooterBuilder() { Text('底部信息') .fontSize(14) .fontColor(Color.Gray) } @Builder ContentBuilder() { Column() { this.HeaderBuilder('主标题') Text('这里是内容区域...') this.FooterBuilder() } } build() { Column() { this.ContentBuilder() } } } ``` ### 总结 使用@Builder装饰器可以有效地复用UI代码,提高开发效率。关键点包括: - 私有@Builder组件内定义,全局@Builder组件外定义。 - 默认按值传递参数,若希望响应状态变化,需使用按引用传递(在参数前加`$`,并使用`$$`传递状态变量)。 - 在组件内@Builder中,可以通过`this`访问组件的状态变量。 通过合理使用@Builder,可以构建出结构清晰、易于维护的UI代码。 [^1]: HarmonyOS开发者文档中心 - ArkTS @Builder装饰器 [^2]: OpenHarmony实战——自定义构建函数@Builder装饰器 [^3]: ArkTS @Builder装饰器自定义构建函数 [^4]: 构建ArkTS@Builder装饰器自定义构建函数 §§相关问题§§ 1. 如何理解ArkTS@Builder装饰器的按引用传递? 2. 全局@Builder组件内@Builder有什么区别? 3.@Builder中如何访问外部组件的状态变量? 4. @Builder装饰器自定义组件有何异同? 5. 如何避免在@Builder中产生不必要的UI刷新? </think>### @Builder装饰器的使用方法详解 @Builder是ArkUI提供的轻量级UI元素复用机制,用于创建可复用的UI构建函数。以下是具体使用方法: #### 1. **基本定义语法** ```typescript // 组件内私有构建函数 @Builder myBuilder() { // UI结构 } // 全局构建函数 @Builder function GlobalBuilder() { // UI结构 } ``` #### 2. **组件内私有构建函数** 在自定义组件内部使用,通过`this`访问组件状态: ```typescript @Component struct MyComponent { @State counter: number = 0 // 私有构建函数 @Builder CounterButton() { Button(`点击 ${this.counter}`) .onClick(() => this.counter++) .margin(10) } build() { Column() { this.CounterButton() // 调用构建函数 this.CounterButton() // 复用UI } } } ``` #### 3. **全局构建函数** 定义在组件外部,可在任意组件中调用: ```typescript // 全局构建函数[^2] @Builder function RedButton(label: string) { Button(label) .backgroundColor(Color.Red) .fontColor(Color.White) } @Entry @Component struct HomePage { build() { Column() { RedButton('警告') // 全局调用 RedButton('危险') } } } ``` #### 4. **参数传递方式** - **按值传递**(默认):状态变量更新不会触发UI刷新 ```typescript @Builder function StaticBuilder(param: string) { Text(param) // 不会响应外部变化 } ``` - **按引用传递**(推荐):使用`$`前缀响应状态变化[^3] ```typescript @Builder function DynamicBuilder($param: string) { Text($param) // 响应外部状态变化 } // 调用时 DynamicBuilder($$this.stateVar) ``` #### 5. **最佳实践** 1. **访问组件状态**:在私有构建函数中直接通过`this`访问 ```typescript @Builder ThemeButton() { Button(this.buttonText) // 直接访问组件状态 .backgroundColor(this.themeColor) } ``` 2. **组合使用**:构建函数可嵌套调用 ```typescript @Builder FormItem(label: string) { Row() { Text(label).width('30%') RedButton('提交') // 调用其他构建函数 } } ``` 3. **样式分离**:@Styles配合使用 ```typescript @Styles function cardStyle() { .padding(10) .backgroundColor(Color.White) } @Builder function InfoCard() { Column() { // 内容 }.style(cardStyle) // 应用样式 } ``` #### 6. **自定义组件的区别** | 特性 | @Builder构建函数 | 自定义组件 | |--------------|-----------------------|-------------------| | 复用粒度 | UI片段 | 完整组件 | | 状态管理 | 依赖父组件状态 | 自有状态管理 | | 生命周期 | 无 | 完整生命周期 | | 参数传递 | 灵活的直接参数传递 | 通过属性参数传递 | | 最佳场景 | 简单UI复用 | 复杂独立功能模块 | [^1]: HarmonyOS开发者文档中心 - @Builder装饰器 [^2]: OpenHarmony实战 - 自定义构建函数 [^3]: ArkTS @Builder参数传递规范 [^4]: 构建ArkTS@Builder装饰器
评论 8
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

鸿蒙Next

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值