鸿蒙应用开发之@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更新不生效。 对鸿蒙感兴趣的同学,免费考取鸿蒙开发者认证

相关推荐
爱写代码的阿森7 小时前
鸿蒙三方库 | harmony-utils之EncryptUtil AES对称加密详解
华为·harmonyos·鸿蒙·huawei
爱写代码的阿森7 小时前
鸿蒙三方库 | harmony-utils之FileUtil文件管理与目录详解
华为·harmonyos·鸿蒙·huawei
爱写代码的森9 小时前
鸿蒙三方库 | harmony-utils之DateUtil日期计算详解
华为·harmonyos·鸿蒙·huawei
youtootech9 小时前
HarmonyOS 6.0 长按菜单与拖拽预览
华为·harmonyos
特立独行的猫a11 小时前
鸿蒙PC Node.js三方库移植的AI移植框架与社区贡献完整流程
华为·node.js·harmonyos·三方库移植·鸿蒙pc
FF2501_9402285811 小时前
HarmonyOS应用《玄象》开发实战:FortuneTimelinePage 运势时间线:Timeline 自定义组件 + List 虚拟滚动
harmonyos·鸿蒙
LEO1111011 小时前
HarmonyOS应用开发实战:猫猫大作战-概率生成算法
harmonyos·鸿蒙
进击的丸子11 小时前
APP人脸识别增值版Harmony Demo实操与关键代码解析
前端·程序员·harmonyos
LEO1111012 小时前
HarmonyOS应用开发实战:猫猫大作战-样式抽成可复用类,一处定义、多处复用,还能针对不同状态(正常/按下/禁用)应用不同样式
harmonyos·鸿蒙
熊猫钓鱼>_>14 小时前
当3DGS遇上ArkTS:用HarmonyOS端侧重建守护文化遗产——从零构建「古韵新生」完整工程
3d·华为·harmonyos·arkts·鸿蒙·3dgs