当前位置: 首页 > news >正文

鸿蒙UI开发——Builder函数的封装

1、问题引入

我们在开发中可能会遇到这样一个问题:将一个@Builder修饰后的函数用变量或者数组记录下来,在业务其他地方使用这些@Builder函数。

举个例子,有下面一段代码:

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

我们试图将builderElement这个builder方法放到builderArr数组中,然后统一在另一个Builder方法(testBuilder)中遍历执行。

此时,我们在IDE中可以看到,会报一个如下的错误:

图片

'item()' does not comply with the UI component syntax. <ArkTSCheck>

为了解决这样的问题,ArkUI提供了wrapBuilder来让我们对Builder函数做封装。本文对wrapBuilder的使用做简单讨论。

2、wrapBuilder

wrapBuilder是一个模板函数,返回一个WrappedBuilder对象。其接口定义如下:

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

其中 WrappedBuilder对象也是一个模板类。定义如下:​​​​​​​

// 模板参数<Args extends Object[]>是需要包装的builder函数的参数列表declare class WrappedBuilder< Args extends Object[]> {  builder: (...args: Args) => void;  constructor(builder: (...args: Args) => void);}

📢📢需要注意:

  • wrapBuilder方法只能传入全局@Builder方法。

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

3、案 例

我们有了wrapBuilder后,开篇的代码我们就可以改造为如下(注意第3行、第7 ~ 8行):​​​​​​​

@Builderfunction builderElement() {}let builderArr: WrappedBuilder<[]>[] = [wrapBuilder(builderElement)];@Builderfunction testBuilder() {  ForEach(builderArr, (item: WrappedBuilder<[]>) => {    item.builder();  })}

我们可以注意到第3行的WrappedBuilder定义,泛型参数是一个空数组,即:WrappedBuilder<[]>,表示我们包装的builder函数是空参数。

如果我们的builder函数有传入参数,那对应在数组中按顺序传入对应的类型即可。

例如,我们将builderElement改造为有两个入参的函数,第一个是string类型,第二个是number类型,那代码将是如下(第3行、第7 ~ 8行):​​​​​​​

@Builderfunction builderElement(name: string, count: number) {}let builderArr: WrappedBuilder<[string, number]>[] = [wrapBuilder(builderElement)];@Builderfunction testBuilder() {  ForEach(builderArr, (item: WrappedBuilder<[string, number]>) => {    item.builder('欢迎加入【Harmony自习室】!', 1);  })}

除了将wrappedBuilder放到数组中,我们也可以直接赋值给变量。一个案例如下(第7行、第17行):​​​​​​​

@Builderfunction MyBuilder(value: string, size: number) {  Text(value)    .fontSize(size)}let globalBuilder: WrappedBuilder<[string, number]> = wrapBuilder(MyBuilder);@Entry@Componentstruct Index {  @State message: string = 'Hello World';  build() {    Row() {      Column() {        globalBuilder.builder(this.message, 50)      }      .width('100%')    }    .height('100%')  }}

‼️wrapBuilder不支持重复定义‼️

wrapBuilder(MyBuilderFirst)只在第一次定义时生效。即:

通过wrapBuilder(MyBuilderFirst)初始化定义builderObj之后,再次对builderObj进行赋值wrapBuilder(MyBuilderSecond)将不会起作用。示例代码如下:​​​​​​​

@Builderfunction MyBuilderFirst(value: string, size: number) {  Text('MyBuilderFirst:' + value)    .fontSize(size)}@Builderfunction MyBuilderSecond(value: string, size: number) {  Text('MyBuilderSecond:' + value)    .fontSize(size)}interface BuilderModel {  globalBuilder: WrappedBuilder<[string, number]>;}@Entry@Componentstruct Index {  @State message: string = 'Hello World';  @State builderObj: BuilderModel = { globalBuilder: wrapBuilder(MyBuilderFirst) };  aboutToAppear(): void {    setTimeout(() => {      this.builderObj.globalBuilder = wrapBuilder(MyBuilderSecond);    },1000)  }  build() {    Row() {      Column() {        this.builderObj.globalBuilder.builder(this.message, 20)      }      .width('100%')    }    .height('100%')  }}

相关文章:

  • 怎么开发一个网络协议模块(C语言框架)之(一) main
  • 连接表、视图和存储过程
  • 使用LLaMA-Factory微调ollama中的大模型(二)------使用数据集微调大模型
  • 织梦dedecms上传附件不自动改名的办法
  • Vanna.AI:解锁连表查询的新境界
  • ae钢笔工具无法编辑形状图层的路径
  • WPS 64位与EndNote21.5工作流
  • Eigen 直线拟合/曲线拟合/圆拟合/椭圆拟合
  • leetcode hot100刷题日记——14.二叉树的最大深度
  • CAU人工智能class5 激活函数
  • IPD推行成功的核心要素(十二)CDP确保产品开发的正确方向
  • XOR符号
  • UE5 图片导入,拖到UI上变色
  • 在Visual Studio中进行cuda编程
  • Axure元件动作六:设置图片
  • 滚珠导轨在航空航天领域具体应用是什么?
  • 使用腾讯云3台轻量云服务器快速部署K8s集群实战
  • 独立机构软件第三方检测:流程、需求分析及电商软件检验要点?
  • RAID技术全解析:从基础到实战应用指南
  • 信息安全管理与评估2025上海卷
  • 昆山做网站的那家好/网络服务投诉平台
  • 婚纱影楼网站模板/百度开户怎么开
  • 动态网站建设简介/网站搜索优化技巧
  • 网站备案上传照片几寸/天津百度网站快速优化
  • 德阳手机网站建设/关键词分析工具
  • 免费网络咨询免费建站/自动点击竞价广告软件