学习笔记(四十四):自定义组件@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) } }
作者:听着music睡
出处:http://www.cnblogs.com/xqxacm/
Android交流群:38197636
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。