学习笔记(四十四):自定义组件@LocalBuilder装饰器

概述:

当开发者使用@Builder做引用数据传递时,会考虑组件的父子关系,使用了bind(this)之后,组件的父子关系和状态管理的父子关系并不一致。

为了解决组件的父子关系和状态管理的父子关系保持一致的问题,引入@LocalBuilder装饰器。

@LocalBuilder拥有和局部@Builder相同的功能,且比局部@Builder能够更好的确定组件的父子关系和状态管理的父子关系。

示例:

1、定义自定义组件

// 自定义组件
@Component
export struct CommonView{
  @State msg:string = "子 Child"
  @Builder customBuilder() {};
  @BuilderParam customBuilderParam:()=>void=this.customBuilder
  build() {
    Column() {
      this.customBuilderParam()
    }
  }
}

2、使用该自定义组件 

import { CommonView } from "../components/CommonView";
@Entity
@Component
export struct Main {
  @State msg:string = "父Parent"

  // 通过this.componentBuilder的形式传给子组件@BuilderParam customBuilderParam,this指向在Child的label,即“Child”。
  @Builder customerBuilder(){
    Text(this.msg)
  }
  // 过this.componentBuilder的形式传给子组件@BuilderParam customBuilderParam,this指向Parent的label,即“Parent”。
  @LocalBuilder customerBuilder(){
    Text(this.msg)
  }
  build() {
    Column() {
      Text('Main')
      CommonView({customBuilderParam:this.customerBuilder})
      Text('End')
    }.width('100%').justifyContent(FlexAlign.Center)
  }
}

使用@Builder装饰的效果图:

使用@LocalBuilder装饰的效果图:

 

@LocalBuilder和@Builder区别说明

说明:

@Builder componentBuilder()通过this.componentBuilder的形式传给子组件@BuilderParam customBuilderParam,this指向在Child的label,即“Child”。

@LocalBuilder componentBuilder()通过this.componentBuilder的形式传给子组件@BuilderParam customBuilderParam,this指向Parent的label,即“Parent”。

 

 

参数传递规则:

  • 参数的类型必须与参数声明的类型一致,不允许undefined、null和返回undefined、null的表达式。

  • 在@LocalBuilder修饰的函数内部,不允许改变参数值。

  • @LocalBuilder内UI语法遵循UI语法规则

  • 只有传入一个参数,且参数需要直接传入对象字面量才会按引用传递该参数,其余传递方式均为按值传递。

1、值传递

当传递的参数为状态变量时,状态变量的改变不会引起@LocalBuilder方法内的UI刷新。所以当使用状态变量的时候,推荐使用按引用传递。

如下 点击事件 修改自定义组件参数内容后,自定义组件并不会刷新UI

import { ViewEntity } from "../animation/ViewEntity";
import { CommonView } from "../components/CommonView";

@Entity
@Component
export struct Main {
  @State viewEntity:ViewEntity = new ViewEntity();
  @Builder customerBuilder(content:string){
    Text(content) // 显示值传递的内
  }
  build() {
    Column() {
      Text('Main')
      this.customerBuilder(this.viewEntity.content) // 使用自定义组件,传值字符串内容
      Text('End')
      Button('修改数值').onClick(()=>{
        this.viewEntity.content = "修改后的内容" 
      })
    }.width('100%').justifyContent(FlexAlign.Center)
  }
}

 

2、引用传递

按引用传递参数时,如果在@LocalBuilder方法内调用自定义组件,ArkUI提供$$作为按引用传递参数的范式。

组件Parent内的@LocalBuilder方法内调用自定义组件,且按照引用传递参数将值传递到自定义组件,

当Parent组件内状态变量值发生变化时,@LocalBuilder方法内的自定义组件HelloComponent的message值也会发生变化。

import { ViewEntity } from "../animation/ViewEntity";
import { CommonView } from "../components/CommonView";

@Entity
@Component
export struct Main {
  @State viewEntity:ViewEntity = new ViewEntity();

  @Builder customerBuilder($$:ViewEntity){
    Text($$.content) // 显示值传递的内
  }

  build() {
    Column() {
      Text('Main')
      this.customerBuilder({content:this.viewEntity.content})
      Text('End')
      Button('修改数值').onClick(()=>{
        this.viewEntity.content = "修改后的内容"
      })
    }.width('100%').justifyContent(FlexAlign.Center)
  }
}

 

 

posted @ 2024-11-24 23:00  听着music睡  阅读(72)  评论(0编辑  收藏  举报