鸿蒙开发:wrapBuilder来封装全局@Builder

简介: 首先第一点,在同一个UI组件内,同一个wrapBuilder只能初始化一次,第二点就是WrappedBuilder对象的builder属性方法只能在struct内部使用。

前言


本文代码案例基于Api13。


@Builder装饰器,可以把build函数中的组件代码,单独的抽取出来,虽然简化了build函数,实现了组件之间的复用,但是代码还是在整个UI视图内,如下案例所示:


@Entry
@Component
struct Index {
  @Builder
  TextView(text: string) {
    Text(text)
  }
  build() {
    Column() {
      this.TextView("测试数据1")
      this.TextView("测试数据2")
    }
    .height('100%')
    .width('100%')
    .justifyContent(FlexAlign.Center)
  }
}


只能说,在同一个UI视图中,实现了组件复用,简化了代码,但是,如果有很多个页面共用一个组件呢?还好,@Builder装饰器支持全局定义,这个在以往的文章中有过概述,可以把共用的组件抽取到一个全局文件中。


@Builder
export function TextView(text: string) {
  Text(text)
}


在需要的地方直接调用即可。


import { TextView } from './Views'
@Entry
@Component
struct Index {
  build() {
    Column() {
     TextView("测试数据1")
     TextView("测试数据2")
    }
    .height('100%')
    .width('100%')
    .justifyContent(FlexAlign.Center)
  }
}


哎,回过头来,我们发现,@Builder装饰器可局部可全局,已经满足了需求了啊,还要wrapBuilder干什么?先别着急,我们先看下这几个场景:


1、有一个自定义Dialog弹窗,需要接收从外部传递UI视图过来,请问,如何把组件传递过去?


2、有一个封装的网络库,其中有一个功能是请求加载Loading,由于每个项目的Loading不同,这个Loading组件视图需要单独传递,如何传递?


怎么能把外部定义的UI组件,传递给需要的地方呢?这些需要的地方可不是struct修饰的,大家想想看,能直接传递吗?


再看一个案例,虽然说,我们可以定义全局的@Builder装饰器,然而当我组合成数组后,却无法进行调用,如下代码:


import { TextView } from './Views';
let builderArr: Function[] = [TextView]
@Entry
@Component
struct Index {
  
  build() {
    Column() {
      ForEach(builderArr, (item: Function) => {
        item()
      })
    }
    .height('100%')
    .width('100%')
    .justifyContent(FlexAlign.Center)
  }
}


直接报错:


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


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


如何使用


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

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


声明变量


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


简单案例:

import { TextView } from './Views'
@Entry
@Component
struct Index {
  textView: WrappedBuilder<[string]> = wrapBuilder(TextView)
  build() {
    Column() {
      this.textView.builder("测试数据")
    }
    .height('100%')
    .width('100%')
    .justifyContent(FlexAlign.Center)
  }
}


当然了,也可以直接在定义组件的地方进行声明变量。

@Builder
function TextView(test: string) {
  Text(test)
}
export let textView: WrappedBuilder<[string]> = wrapBuilder(TextView)


调用:

import { textView } from './Views'
@Entry
@Component
struct Index {
  build() {
    Column() {
      textView.builder("测试数据")
    }
    .height('100%')
    .width('100%')
    .justifyContent(FlexAlign.Center)
  }
}


传递数据


其实在上边的案例中,已经是传递参数的案例,遵循着,接收什么类型就传递什么类型。

比如接收的是string类型。

let textView: WrappedBuilder<[string]> = wrapBuilder(TextView)


比如接收两个参数,一个是string,一个是number。


@Builder
function TextView(test: string,num:number) {
  Text(test)
}
export let textView: WrappedBuilder<[string,number]> = wrapBuilder(TextView)


如果传递参数过多,可以通过对象,数组,集合等形式传递,下面举一个引用类型传递:

定义对象


export class TestBean {
  testData?: string = "测试数据"
}


创建全局组件


import { TestBean } from "./TestBean"
@Builder
function TextView(test: TestBean) {
  Text(test.testData)
}
export let textView: WrappedBuilder<[TestBean]> = wrapBuilder(TextView)


组件调用


import { TestBean } from './TestBean';
import { textView } from './Views'
@Entry
@Component
struct Index {
  @State test: TestBean = new TestBean();
  build() {
    Column() {
      textView.builder({ testData: this.test.testData })
      Button("点击").onClick(() => {
        this.test.testData = "改变数据"
      })
    }
    .height('100%')
    .width('100%')
    .justifyContent(FlexAlign.Center)
  }
}


相关总结


首先第一点,在同一个UI组件内,同一个wrapBuilder只能初始化一次,第二点就是WrappedBuilder对象的builder属性方法只能在struct内部使用。


如何接收一个外部传来的UI组件呢,很是简单,只需要接收一个WrappedBuilder<[Object]>即可,简单案例如下:


export class ViewUtils {
  view?: WrappedBuilder<[Object]>
  setView(view: WrappedBuilder<[Object]>) {
    this.view = view
  }
  getView(): WrappedBuilder<[Object]> | undefined {
    return this.view
  }
}
相关文章
|
28天前
|
人工智能 物联网 Android开发
【04】优雅草星云物联网AI智控系统从0开发鸿蒙端适配-deveco studio-自定义一个设置输入小部件组件-完成所有设置setting相关的页面-优雅草卓伊凡
【04】优雅草星云物联网AI智控系统从0开发鸿蒙端适配-deveco studio-自定义一个设置输入小部件组件-完成所有设置setting相关的页面-优雅草卓伊凡
160 92
|
28天前
|
人工智能 物联网 Android开发
【03】优雅草星云物联网AI智控系统从0开发鸿蒙端适配-deveco studio-在lib目录新建自定义库UtilsLibrary,ComponentLibrary,CommonConstLibrary完成设置SettingsView.ets初始公共类书写-优雅草卓伊凡
【03】优雅草星云物联网AI智控系统从0开发鸿蒙端适配-deveco studio-在lib目录新建自定义库UtilsLibrary,ComponentLibrary,CommonConstLibrary完成设置SettingsView.ets初始公共类书写-优雅草卓伊凡
71 23
【03】优雅草星云物联网AI智控系统从0开发鸿蒙端适配-deveco studio-在lib目录新建自定义库UtilsLibrary,ComponentLibrary,CommonConstLibrary完成设置SettingsView.ets初始公共类书写-优雅草卓伊凡
|
28天前
|
存储 人工智能 物联网
【02】优雅草星云物联网AI智控系统从0开发鸿蒙端适配-deveco studio-登录页面LoginView.ets完成-并且详细解释关于arkui关于 CommonConst, commonColor, InputDataModel-优雅草卓伊凡
【02】优雅草星云物联网AI智控系统从0开发鸿蒙端适配-deveco studio-登录页面LoginView.ets完成-并且详细解释关于arkui关于 CommonConst, commonColor, InputDataModel-优雅草卓伊凡
59 14
【02】优雅草星云物联网AI智控系统从0开发鸿蒙端适配-deveco studio-登录页面LoginView.ets完成-并且详细解释关于arkui关于 CommonConst, commonColor, InputDataModel-优雅草卓伊凡
|
28天前
|
人工智能 物联网 编译器
【01】优雅草星云物联网AI智控系统从0开发鸿蒙端适配完成流程-初始化鸿蒙编译器deveco studio项目结构-UI设计图切片下载-优雅草卓伊凡
【01】优雅草星云物联网AI智控系统从0开发鸿蒙端适配完成流程-初始化鸿蒙编译器deveco studio项目结构-UI设计图切片下载-优雅草卓伊凡
48 11
【01】优雅草星云物联网AI智控系统从0开发鸿蒙端适配完成流程-初始化鸿蒙编译器deveco studio项目结构-UI设计图切片下载-优雅草卓伊凡
|
24天前
|
人工智能 JavaScript 数据安全/隐私保护
鸿蒙开发难题多到崩溃?然而 10 亿终端暗藏财富密码-卓伊凡
鸿蒙开发难题多到崩溃?然而 10 亿终端暗藏财富密码-卓伊凡
50 5
鸿蒙开发难题多到崩溃?然而 10 亿终端暗藏财富密码-卓伊凡
|
12天前
|
人工智能 前端开发 物联网
【05】20250416优雅草星云物联网AI智控系统从0开发鸿蒙端适配-deveco studio-增加告警中心相关卡片页面WarningCardWidget相关-增加Canvas 绘制折线图-Canvas 绘制柱状图-首页-优雅草卓伊凡
【05】20250416优雅草星云物联网AI智控系统从0开发鸿蒙端适配-deveco studio-增加告警中心相关卡片页面WarningCardWidget相关-增加Canvas 绘制折线图-Canvas 绘制柱状图-首页-优雅草卓伊凡
34 0
【05】20250416优雅草星云物联网AI智控系统从0开发鸿蒙端适配-deveco studio-增加告警中心相关卡片页面WarningCardWidget相关-增加Canvas 绘制折线图-Canvas 绘制柱状图-首页-优雅草卓伊凡
|
18天前
|
缓存 开发工具 开发者
鸿蒙NEXT开发App相关工具类(ArkTs)
这段代码展示了一个名为鸿蒙NEXT开发 `AppUtil` 的工具类,主要用于管理鸿蒙应用的上下文、窗口、状态栏、导航栏等配置。它提供了多种功能,例如设置灰阶模式、颜色模式、字体类型、屏幕亮度、窗口属性等,并支持获取应用包信息(如版本号、包名等)。该工具类需在 UIAbility 的 `onWindowStageCreate` 方法中初始化,以便缓存全局变量。代码由鸿蒙布道师编写,适用于鸿蒙系统应用开发,帮助开发者更便捷地管理和配置应用界面及系统属性。
|
6天前
|
安全 前端开发 Android开发
拥抱国产化:转转APP的鸿蒙NEXT端开发尝鲜之旅
本文将要分享的是转转APP在开发全新鸿蒙NEXT端所遇到的一些问题,对比了鸿蒙开发和 Android、iOS 的不同,总结了这次开发过程中的一些经验等等。希望能带给你启发。
18 0
|
28天前
|
前端开发
鸿蒙开发:使用Ellipse绘制椭圆
除了使用Ellipse组件可以一个椭圆之外,我们还可以使用Canvas来绘制一个椭圆,但是相对来说,还是没有Ellipse组件高效,所以,如果说Ellipse组件能够满足需求,还是以Ellipse组件为主。
鸿蒙开发:使用Ellipse绘制椭圆
|
28天前
|
前端开发
鸿蒙开发:使用Circle绘制圆形
绘制矩形也好,圆形也好,大家做为一个了解即可,在有需要用到的场景中,合理的使用即可,毕竟现成的组件,要比自己用别的方式实现要简单的多。
鸿蒙开发:使用Circle绘制圆形