鸿蒙应用开发之@Builder自定义构建函数:值传递与引用传递与UI更新

@Builder装饰器:自定义构建函数

@Builder装饰的函数称为自定义构建函数 ,它是一种轻量化 UI 复用机制,它允许开发者将重复使用的 UI 元素抽象为函数,这些函数可以在 build 函数中被调用以实现 UI 复用。

自定义构建函数根据定义的位置不同分为私有自定义函数全局自定义函数

私有自定义构建函数

私有自定义构建函数定义在@Component组件内,属于该组件私有的,只能在该组件内build函数或者其他自定义构建函数中调用。

ts{9-12,5} 复制代码
@Component
struct MyComponent {
  build() {
    Column() {
      this.myBuilder()
    }
  }

  @Builder
  myBuilder() {
    Text("私有@Builder")
  }
}

@Entry
@Component
struct Index {
  build() {
    Column({ space: 10 }) {
      MyComponent()
    }
    .width("100%")
    .height("100%")
  }
}

全局自定义构建函数

全局自定义函数定义在@Component组件外,可以在其他自定义函数或者其他自定义组件中调用。

ts{1-4,11} 复制代码
@Builder
function myBuilder() {
  Text("全局@Builder")
}

@Entry
@Component
struct Index {
  build() {
    Column({ space: 10 }) {
      myBuilder()
    }
    .width("100%")
    .height("100%")
  }
}

@Builder与@Component的区别

经过上面的描述可能会发现@Component和@Builder都可以用于UI复用,他们的区别如下:

  • @Builder:纯UI逻辑复用,无独立状态管理与生命周期,必须通过参数传递的方式与调用方完成数据交互。
  • @Component:完整组件封装,拥有独立状态管理与生命周期。

自定义构建函数参数传递规则

自定义构建函数的参数传递有按值传递按引用传递两种,均需遵守以下规则:

  • 参数的类型必须与参数声明的类型一致,不允许undefined、null和返回undefined、null的表达式。
  • @Builder装饰的函数内部,不允许改变参数值。
  • 只有当传入一个参数且该参数直接传入对象字面量时,才会按引用传递,其他传递方式均为按值传递。

按值传递参数

定义一个全局自定义构建函数textBuilder(text: string),参数只有一个且不是字面量对象,所以按照值传递。

ts 复制代码
@Builder
function textBuilder(text: string) {
  Text("Hello,"+text).fontSize(30)
}

调用@Builder装饰的函数默认按值传递。当传递的参数为状态变量时,状态变量的改变不会引起@Builder函数内的UI刷新

ts 复制代码
@Entry
@Component
struct Index {
  @State text: string = 'World'

  build() {
    Column() {
      textBuilder(this.text)
      Button("修改text").onClick(() => {
        //修改状态变量,不会引用@Builder函数中UI的更新
        this.text = "ArkUI"
      })
    }
  }
}

如下图,经测试状态变量的改变不会引起@Builder函数内UI刷新

按引用传递参数

定义一个@Builder自定义构建函数,参数为自定义对象类型。

ts 复制代码
class Params {
  text: string = ''
}

@Builder
function textBuilder(params: Params) {
  Text(`Hello, ${params.text}`).fontSize(30)
}

调用按引用传递参数时,传递的参数可为状态变量,且状态变量的改变会引起@Builder函数内的UI刷新。

ts 复制代码
@Entry
@Component
struct Index {
  @State text: string = 'World'

  build() {
    Column() {
      textBuilder({
        text: this.text
      })
      Button("修改text").onClick(() => {
        //修改状态变量,不会引用@Builder函数中UI的更新
        this.text = "ArkUI"
      })
    }
  }
}

预览效果如下图所示:

限制条件

  • @Builder自定义函数内部不允许修改参数值,否则框架会抛出运行时异常。
  • @Builder自定义构建函数存在两个或两个以上的参数时,即使通过对象字面量形式传递,值的改变也不会触发UI刷新。

示例1:在@Builder中修改参数值

ts 复制代码
class Params {
  text: string = ''
}

@Builder
function textBuilder(params: Params) {
  Text(`Hello, ${params.text}`).fontSize(30)
    .onClick(() => {
      params.text = "哈哈哈"	//【错误】,禁止改参数的值
    })
}

如下图所示,出现预览错误

示例2:在@Builder中接收两个参数,不会触发UI更新。

ts 复制代码
import { promptAction } from "@kit.ArkUI"

class Params {
  text: string = ''
}

@Builder
function textBuilder(params: Params,num:number) {
  Column(){
    Text(`Hello, ${params.text}`).fontSize(30)
      .onClick(() => {
        params.text = "哈哈哈"
      })

    Text(`${num}`)
  }

}

@Entry
@Component
struct Index {
  @State text: string = 'World'

  build() {
    Column() {
      textBuilder({
        text: this.text
      },100)
      Button("修改text").onClick(() => {
        //修改状态变量,不会引用@Builder函数中UI的更新
        this.text = "ArkUI"
      })
    }
  }
}

如下图,当@Builder接收2个参数时,UI更新不生效。 对鸿蒙感兴趣的同学,免费考取鸿蒙开发者认证

相关推荐
独守一片天14 小时前
HarmonyOS 鸿蒙碰一碰与跨端协同体验怎么设计?
华为·harmonyos
yuhulkjv33517 小时前
Gemini鸿蒙版导出word格式的终极解法:AI 导出鸭如何重构AI内容落地链路
人工智能·ai·word·harmonyos·ai导出鸭
whyutianict_vv20 小时前
从 Web 前端到 HarmonyOS ArkTS:一次 AI 鸿蒙全栈智能体开发的迁移实录
前端·人工智能·harmonyos
m0_7496902320 小时前
【寻迹校园 HarmonyOS NEXT 实战 01】从校园痛点到可上架 MVP:失物招领应用产品设计
人工智能·深度学习·移动开发·harmonyos·arkts·arkui·产品设计
m0_7496902320 小时前
【寻迹校园 HarmonyOS NEXT 实战 03】NavPathStack 路由实战:18 个页面如何集中管理
华为·移动开发·harmonyos·arkui·navigation·navpathstack
m0_7496902321 小时前
【寻迹校园 HarmonyOS NEXT 实战 02】多模块工程拆解:entry、HAR 与 HSP 如何分工
华为·harmonyos·arkts·软件架构·har·hsp
用户0934077735141 天前
HarmonyOS WPS Open SDK 实践:用 SdkConstants 判断当前 HAR 形态
harmonyos
独守一片天1 天前
HarmonyOS鸿蒙新生态智能体意图框架怎么设计?
华为·harmonyos
梦想不只是梦与想1 天前
鸿蒙应用api的兼容性:参数配置(二)
harmonyos·sdk版本·sdkversion
北墨NoLimit2 天前
鸿蒙线程间通信怎么选:TaskPool、TaskGroup、LongTask 与 Worker 实战
typescript·harmonyos