harmony 鸿蒙wrapBuilder:封装全局@Builder

  • 2025-06-16
  • 浏览 (1)

wrapBuilder:封装全局@Builder

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

在阅读本文档前,建议提前阅读:\@Builder

说明:

从API version 11开始使用。

当@Builder方法赋值给变量或者数组后,在UI方法中无法使用。

@Builder
function builderElement() {}

let builderArr: Function[] = [builderElement];
@Builder
function testBuilder() {
  ForEach(builderArr, (item: Function) => {
    item();
  })
}

在上述代码中,builderArr是一个由@Builder方法组成的数组。在ForEach循环中取每个@Builder方法时,会出现@Builder方法在UI方法中无法使用的问题。

为了解决这一问题,引入wrapBuilder作为全局@Builder封装函数。wrapBuilder返回WrappedBuilder对象,实现全局\@Builder可以进行赋值和传递。

接口说明

wrapBuilder是一个模板函数,返回一个WrappedBuilder对象。

declare function wrapBuilder<Args extends Object[]>(builder: (...args: Args) => void): WrappedBuilder<Args>;

同时 WrappedBuilder对象也是一个模板类。

declare class WrappedBuilder<Args extends Object[]> {
  builder: (...args: Args) => void;

  constructor(builder: (...args: Args) => void);
}

说明:模板参数Args extends Object[]是需要包装的builder函数的参数列表

使用方法:

let builderVar: WrappedBuilder<[string, number]> = wrapBuilder(MyBuilder);
let builderArr: WrappedBuilder<[string, number]>[] = [wrapBuilder(MyBuilder)]; //可以放入数组

限制条件

  1. wrapBuilder方法只能传入全局\@Builder方法。

  2. wrapBuilder方法返回的WrappedBuilder对象的builder属性方法只能在struct内部使用。

@Builder方法赋值给变量

使用@Builder装饰器装饰的方法MyBuilder作为wrapBuilder的参数,再将wrapBuilder函数的返回值赋值给变量globalBuilder,以解决@Builder方法赋值给变量后无法使用的问题。

@Builder
function MyBuilder(value: string, size: number) {
  Text(value)
    .fontSize(size)
}

let globalBuilder: WrappedBuilder<[string, number]> = wrapBuilder(MyBuilder);

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

  build() {
    Row() {
      Column() {
        globalBuilder.builder(this.message, 50)
      }
      .width('100%')
    }
    .height('100%')
  }
}

@Builder方法赋值给变量在UI语法中使用

自定义组件Index使用ForEach进行不同@Builder函数的渲染,可以使用builderArr声明的wrapBuilder数组来实现不同的@Builder函数效果。整体代码会更加整洁。

@Builder
function MyBuilder(value: string, size: number) {
  Text(value)
    .fontSize(size)
}

@Builder
function YourBuilder(value: string, size: number) {
  Text(value)
    .fontSize(size)
    .fontColor(Color.Pink)
}

const builderArr: WrappedBuilder<[string, number]>[] = [wrapBuilder(MyBuilder), wrapBuilder(YourBuilder)];


@Entry
@Component
struct Index {
  @Builder
  testBuilder() {
    ForEach(builderArr, (item: WrappedBuilder<[string, number]>) => {
      item.builder('Hello World', 30)
    }

    )
  }

  build() {
    Row() {
      Column() {
        this.testBuilder()
      }
      .width('100%')
    }
    .height('100%')
  }
}

引用传递

按引用传递参数时,传递的状态变量的改变会引起@Builder方法内的UI刷新。

class Tmp {
  paramA2: string = 'hello';
}

@Builder
function overBuilder(param: Tmp) {
  Column() {
    Text(`wrapBuildervalue:${param.paramA2}`)
  }
}

const wBuilder: WrappedBuilder<[Tmp]> = wrapBuilder(overBuilder);

@Entry
@Component
struct Parent {
  @State label: Tmp = new Tmp();

  build() {
    Column() {
      wBuilder.builder({ paramA2: this.label.paramA2 })
      Button('Click me').onClick(() => {
        this.label.paramA2 = 'ArkUI';
      })
    }
  }
}

常见问题

重复定义wrapBuilder失效

在同一个自定义组件内,同一个wrapBuilder只能初始化一次。示例中,builderObj通过wrapBuilder(MyBuilderFirst)初始化定义后,再次对builderObj赋值wrapBuilder(MyBuilderSecond)不会生效。

@Builder
function MyBuilderFirst(value: string, size: number) {
  Text('MyBuilderFirst:' + value)
    .fontSize(size)
}

@Builder
function MyBuilderSecond(value: string, size: number) {
  Text('MyBuilderSecond:' + value)
    .fontSize(size)
}

interface BuilderModel {
  globalBuilder: WrappedBuilder<[string, number]>;
}

@Entry
@Component
struct Index {
  @State message: string = 'Hello World';
  @State builderObj: BuilderModel = { globalBuilder: wrapBuilder(MyBuilderFirst) };

  aboutToAppear(): void {
    setTimeout(() => {
      // wrapBuilder(MyBuilderSecond) 不会生效
      this.builderObj.globalBuilder = wrapBuilder(MyBuilderSecond);
    }, 1000);
  }

  build() {
    Row() {
      Column() {
        this.builderObj.globalBuilder.builder(this.message, 20)
      }
      .width('100%')
    }
    .height('100%')
  }
}

你可能感兴趣的鸿蒙文章

harmony 鸿蒙\@AnimatableExtend装饰器:定义可动画属性

harmony 鸿蒙管理应用拥有的状态概述

harmony 鸿蒙AppStorage:应用全局的UI状态存储

harmony 鸿蒙基本语法概述

harmony 鸿蒙\@Builder装饰器:自定义构建函数

harmony 鸿蒙\@BuilderParam装饰器:引用\@Builder函数

harmony 鸿蒙创建自定义组件

harmony 鸿蒙自定义组件混用场景指导

harmony 鸿蒙自定义组件成员属性访问限定符使用限制

harmony 鸿蒙自定义组件冻结功能

0  赞