HarmonyOS 鸿蒙Next中@Builder传参时可以传入别的Builder吗

HarmonyOS 鸿蒙Next中@Builder传参时可以传入别的Builder吗

[@Builder](/user/Builder) MyTabContent(
  tarbarIndex: [@Builder](/user/Builder),  // 传入任意builder构造
  title: string,
  targetIndex: number,
  selectedImg: Resource,
  normalImg: Resource
) {
  TabContent() {
    this.getBuilder(tarbarIndex)
  }
  // 调用传入的Builder(无需额外参数)
  .tabBar(this.tabBuilder(title,targetIndex,selectedImg,normalImg))
  .backgroundColor("#fff")
}

想实现传入任意builder进行渲染


更多关于HarmonyOS 鸿蒙Next中@Builder传参时可以传入别的Builder吗的实战教程也可以访问 https://www.itying.com/category-93-b0.html

4 回复

有2种方式实现:

1、将 MyTabContent 改为组件, 使用@BuilderParam

@Component
struct MyTabContent {
  [@BuilderParam](/user/BuilderParam) yourBuilder: ()=>void
  build() {
    ...
  }
}

2、使用 WrappedBuilder 封装

@Builder
function MyTabContent(tarbarIndex: WrappedBuilder<[]>) {
  tarbarIndex.builder()
}

@Builder
function paramBuilder() {
  Text('你好')
}

@Builder
function demo() {
  MyTabContent(wrapBuilder(paramBuilder))
}

更多关于HarmonyOS 鸿蒙Next中@Builder传参时可以传入别的Builder吗的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


【背景知识】

[@Builder装饰器:自定义构建函数](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/arkts-builder):ArkUI提供轻量的UI元素复用机制@Builder,其内部UI结构固定,仅与使用方进行数据传递。开发者可将重复使用的UI元素抽象成函数,在build函数中调用。

wrapBuilder:封装全局@Builder:当在一个struct内使用多个全局@Builder函数实现UI的不同效果时,代码维护将变得非常困难,且页面不够整洁。此时,可以使用wrapBuilder封装全局@Builder

wrapBuilder限制条件

  1. wrapBuilder方法只能传入全局@Builder方法。
  2. wrapBuilder方法返回的WrappedBuilder对象的builder属性方法只能在struct内部使用。

【解决方案】

@Builder装饰器修饰函数不支持传递函数方法,仅支持传值,有按值传递和按引用传递两种。但可以通过WrappedBuilder包装类将@Builder的函数包装,之后将WrappedBuilder对象当作变量进行传递。

参考代码如下:

[@Builder](/user/Builder)
function testBuilder() {
  Text('hello world')
}

[@Builder](/user/Builder)
function getBuilder(tarbarIndex: WrappedBuilder<[]>) {
  tarbarIndex.builder()
}

[@Builder](/user/Builder)
function tabBuilder(title: string, targetIndex: number, selectedImg: Resource, normalImg: Resource) {
  Text(title)
}

[@Builder](/user/Builder)
function MyTabContent(tarbarIndex: WrappedBuilder<[]>, title: string, targetIndex: number, selectedImg: Resource, normalImg: Resource) {
  TabContent() {
    getBuilder(tarbarIndex)
  }
  // 调用传入的Builder(无需额外参数)
  .tabBar(tabBuilder(title,targetIndex,selectedImg,normalImg))
  .backgroundColor("#fff")
}

@Entry
@Component
struct Index {
  @State message: string = 'Hello World';

  build() {
    Column(){
      Tabs(){
        MyTabContent(wrapBuilder(testBuilder), 'testA', 0, $r(`app.media.backgroud`), $r(`app.media.backgroud`))
        MyTabContent(wrapBuilder(testBuilder), 'testB', 0, $r(`app.media.backgroud`), $r(`app.media.backgroud`))
      }
    }
  }
}

【总结】

ArkUI通过@Builder装饰器为开发者提供代码精简解决方案,该装饰器不仅能通过模块化封装简化UI开发流程,还衍生出@BuilderParam装饰器、@LocalBuilder装饰器和wrapBuilder,形成完整的可复用的UI结构体系。

  • @Builder装饰器:专为构建模块化、可复用的UI结构而设计,其内部禁止定义状态变量和调用组件生命周期方法,仅支持通过参数与调用方进行数据交互。
  • @BuilderParam装饰器:当多个场景共用同一个@Builder函数时,若需要为特定场景扩展功能(类似slot占位符机制),可通过@BuilderParam装饰器装饰器实现,该装饰器专门用于接收并封装@Builder函数。
  • @LocalBuilder装饰器:在使用@Builder实现组件间数据传递时,开发者需注意组件层级关系。组件树中的父子关系可能与状态管理的父子关系产生不一致。为此,框架提供了@LocalBuilder装饰器装饰器来解决这一特定问题。
  • wrapBuilder:当页面中存在多个具有不同UI结构的全局@Builder函数时,开发者会面临较高的维护成本。为此,框架提供了wrapBuilder机制来简化这一场景下的代码维护工作。

在HarmonyOS鸿蒙Next中,@Builder支持传入其他Builder作为参数。通过函数式参数传递,可以实现Builder的嵌套调用,增强UI组件的复用性与灵活性。具体语法遵循ArkTS的规范,允许将Builder作为参数类型进行声明和传递。

在HarmonyOS Next中,@Builder函数确实支持传入其他@Builder作为参数,但需要注意参数类型声明和调用方式。

根据你的代码示例,参数tarbarIndex的类型应声明为() => void而非@Builder。以下是修正后的写法:

@Builder
MyTabContent(
  tabBuilder: () => void,  // 正确类型声明
  title: string,
  targetIndex: number,
  selectedImg: Resource,
  normalImg: Resource
) {
  TabContent() {
    tabBuilder()  // 直接调用传入的Builder
  }
  .tabBar(this.tabBuilder(title, targetIndex, selectedImg, normalImg))
  .backgroundColor("#fff")
}

使用时直接传入Builder函数名(不带参数):

MyTabContent(this.someBuilder, "标题", 1, $r("app.media.selected"), $r("app.media.normal"))

这种模式适用于需要动态组合UI结构的场景,通过Builder参数实现更高程度的组件复用。

回到顶部