鸿蒙@Builder@BuilderParam和wrapBuilder

以下是鸿蒙 ArkUI 中 @Builder@BuilderParamwrapBuilder 的详细解析与代码案例,涵盖核心概念、使用场景及最佳实践:


⚙️ ​一、@Builder:轻量级 UI 复用

1. ​私有构建函数

定义在组件内部,通过 this 访问组件状态,适合组件内重复 UI 结构复用:

ts 复制代码
@Entry
@Component
struct PrivateBuilderDemo {
  @State count: number = 0;

  // 私有构建函数
  @Builder
  CounterButton() {
    Button(`点击: ${this.count}`)
      .onClick(() => this.count++) // 直接访问组件状态
  }

  build() {
    Column() {
      this.CounterButton() // 调用
      this.CounterButton() // 复用
    }
  }
}

特点​:

  • 通过 this 访问组件状态(如 @State
  • 仅在当前组件内可用

2. ​全局构建函数

独立于组件定义,可跨组件复用,​无法访问组件状态​:

ts 复制代码
// 全局定义
@Builder
function GlobalButton(text: string) {
  Button(text)
    .width(200)
    .backgroundColor(Color.Blue)
}

@Entry
@Component
struct GlobalDemo {
  build() {
    Column() {
      GlobalButton("提交") // 跨组件调用
      GlobalButton("取消")
    }
  }
}

特点​:

  • 通过函数名直接调用
  • 适合无状态 UI(如通用按钮、卡片)

3. ​参数传递规则

  • 值传递(默认)​ ​:

    状态更新不会触发 UI 刷新​(传递副本):

    ts 复制代码
    @Builder
    function ValueDemo(param: string) {
      Text(param) // 值拷贝
    }
  • 引用传递 ​:

    使用对象字面量 传递,状态更新触发 UI 刷新​:

    ts 复制代码
    class Config {
      content: string = ""
    }
    
    @Builder
    function ReferenceDemo($$: Config) {
      Text($$.content) // 引用传递
    }
    
    @Entry
    
    @Component struct Parent {  
    @State config = new Config();  
        build() {  
            Column() {  
                ReferenceDemo({ content: this.config.content }) // 对象字面量  
                Button("更新").onClick(() => this.config.content = "New")  
            }  
        }  
    }

关键点

  • 引用传递需满足:单参数 + 对象字面量
  • 命名约定:推荐用 $$ 标识引用参数

🧩 二、@BuilderParam:动态 UI 插槽

用于在自定义组件中声明 UI 占位符,允许父组件注入 UI 结构:

typescript 复制代码
// 子组件
@Component
struct ChildComponent {
@BuilderParam customUI: () => void // 声明占位符

build() {
  Column() {
    Text("固定内容")
    this.customUI() // 渲染父组件传入的UI
  }
}
}

// 父组件
@Entry
@Component
struct ParentComponent {
@Builder
parentBuilder() {
  Row() {
    Text("父组件传入的内容")
    Image($r('app.media.icon'))
  }
}

build() {
  Column() {
    ChildComponent({ customUI: this.parentBuilder }) // 注入UI
  }
}
}

高级用法​:支持带参数的构建函数

ts 复制代码
@Component
struct ParamChild {
  @BuilderParam paramBuilder: (color: Color) => void

  build() {
    Column() {
      this.paramBuilder(Color.Red) // 传入参数
    }
  }
}

@Entry
@Component
struct ParamParent {
  @Builder
  colorBlock($$: { color: Color }) {
    Text("文本").fontColor($$.color)
  }

  build() {
    ParamChild({ paramBuilder: this.colorBlock })
  }
}

特点​:

  • 类似 Vue 的插槽机制(slot
  • 通过箭头函数保留父组件状态上下文

📦 ​三、wrapBuilder:全局构建器的动态封装

解决全局 @Builder无法存入数组或动态赋值 的问题,返回 WrappedBuilder 对象:

ts 复制代码
// 定义全局构建器
@Builder
function GlobalText(value: string, size: number) {
  Text(value).fontSize(size)
}

// 封装为可存储对象
const wrappedText: WrappedBuilder<[string, number]> = wrapBuilder(GlobalText);

@Entry
@Component
struct WrapDemo {
  @State message: string = "Hello";

  build() {
    Column() {
      wrappedText.builder(this.message, 30) // 调用封装后的构建器
    }
  }
}

动态管理构建器数组​:

ts 复制代码
@Builder
function BuilderA() { Text("A") }
@Builder
function BuilderB() { Text("B") }

// 存入数组
const builderArr: WrappedBuilder<[]>[] = [
  wrapBuilder(BuilderA),
  wrapBuilder(BuilderB)
];

@Entry
@Component
struct ArrayDemo {
  build() {
    Column() {
      ForEach(builderArr, (item) => {
        item.builder() // 遍历调用
      })
    }
  }
}

限制​:

  • 仅支持全局 @Builder
  • 不可重复赋值(需通过中间对象更新)

🔍 ​四、三者的核心差异对比

特性 @Builder @BuilderParam wrapBuilder
作用域 组件内/全局 组件内部 全局构建器
核心用途 封装可复用 UI 片段 声明 UI 插槽占位符 全局构建器的动态管理
状态访问 私有构建器可访问组件状态 通过箭头函数继承父组件状态 需显式传递参数
动态化支持 ❌ 不可存入数组 ❌ 依赖父组件初始化 ✅ 可存入数组、变量传递

⚠️ ​五、避坑指南

  1. ​**@Builder 更新失效
    错误​:多参数或非对象字面量传递状态变量。
    解决**​:封装为单对象参数 。

  2. ​**@BuilderParam 丢失 this
    错误​:Child({ builder: this.parentBuilder })(指向子组件)。
    修正**​:Child({ builder: () => this.parentBuilder() })

  3. ​**wrapBuilder 无法更新
    错误​:直接赋值 this.wrappedBuilder = wrapBuilder(New)
    解决**​:通过中间对象更新:

    ini 复制代码
    @State builderWrapper = { current: wrapBuilder(OldBuilder) };
    // 更新时
    this.builderWrapper = { current: wrapBuilder(NewBuilder) };

通过组合使用这三种机制,可构建高灵活、低耦合的鸿蒙 UI 架构:

  • 基础复用@Builder 封装按钮/卡片等原子组件
  • 动态插槽@BuilderParam 实现可配置弹窗/表格
  • 高阶抽象wrapBuilder 管理主题库或动态仪表盘
相关推荐
安卓开发者32 分钟前
鸿蒙NEXT自定义能力详解:从基础使用到高级技巧
华为·harmonyos
特立独行的猫a2 小时前
HarmonyOS 鸿蒙系统自带的 SymbolGlyph 图标组件详解
华为·harmonyos·图标·symbolglyph
2501_919749032 小时前
鸿蒙:使用EventHub实现多模块之间的通信
华为·harmonyos
2501_919749038 小时前
鸿蒙:使用Emitter进行线程间通信
华为·harmonyos
SuperHeroWu710 小时前
【HarmonyOS 6】仿AI唤起屏幕边缘流光特效
华为·harmonyos·特效·鸿蒙6.0·流光·ai唤起·屏幕边缘
gcios11 小时前
鸿蒙-flutter 混合开发
harmonyos
特立独行的猫a12 小时前
HarmonyOS应用开发之界面列表不刷新问题Bug排查记:从现象到解决完整记录
华为·bug·harmonyos·ui刷新
安卓开发者13 小时前
鸿蒙Next的UI国际化与无障碍适老化实践:构建全球包容的数字世界
ui·华为·harmonyos
爱笑的眼睛111 天前
深入剖析 HarmonyOS ArkUI 声明式开发:状态管理艺术与最佳实践
华为·harmonyos
安卓开发者1 天前
鸿蒙NEXT交互机制解析:从输入设备到手势响应的全面指南
microsoft·交互·harmonyos