鸿蒙@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 管理主题库或动态仪表盘
相关推荐
如此风景4 小时前
如何在一个features下面创建多个HSP?
harmonyos
如此风景6 小时前
鸿蒙开发中 Model 类的组织方式
harmonyos
爱吃大芒果7 小时前
高密度数据可视化渲染:基于 ArkUI Grid 的状态热力图组件开发图纸
华为·信息可视化·harmonyos
心中有国也有家7 小时前
E-Brufen 技术选型全景:Flutter + 鸿蒙 + Hive CE
hive·hadoop·学习·flutter·华为·harmonyos
绝世番茄9 小时前
鸿蒙原生ArkTS布局方式之List+swipeAction侧滑菜单深度解析
华为·list·harmonyos·鸿蒙
Helen_cai9 小时前
OpenHarmony Preferences 本地持久化存储开发(API Version23 + 适配版)
华为·harmonyos
千逐6810 小时前
UniApp 鸿蒙实战:音视频与多媒体处理完全指南
华为·uni-app·harmonyos·鸿蒙
国服第二切图仔11 小时前
HarmonyOS APP《画伴梦工厂》开发第51篇-Skill开发入门——VibeCoding与系统级智能入口
华为·harmonyos
哦***711 小时前
最后一块拼图补齐!华为大豆包时代开启✨
华为·音频·harmonyos
在书中成长11 小时前
HarmonyOS 小游戏《对战五子棋》开发第11篇 - AIPlayer设计概览:三档难度架构
华为·harmonyos