与国外公司合作网站建设上海公司,网站宣传文案范例,广州微网站建设服务,软件工程开发一、前言 当开发者使用Builder做引用数据传递时#xff0c;会考虑组件的父子关系#xff0c;使用了bind(this)之后#xff0c;组件的父子关系和状态管理的父子关系并不一致。为了解决组件的父子关系和状态管理的父子关系保持一致的问题#xff0c;引入LocalBuilder装饰器。…一、前言 当开发者使用Builder做引用数据传递时会考虑组件的父子关系使用了bind(this)之后组件的父子关系和状态管理的父子关系并不一致。为了解决组件的父子关系和状态管理的父子关系保持一致的问题引入LocalBuilder装饰器。LocalBuilder拥有和局部Builder相同的功能且比局部Builder能够更好的确定组件的父子关系和状态管理的父子关系。 在阅读本文档前建议提前阅读Builder。 说明 从API version 12开始支持。 二、装饰器使用说明
2.1 自定义组件内自定义构建函数
定义的语法
LocalBuilder MyBuilderFunction() { ... }使用方法
this.MyBuilderFunction()允许在自定义组件内定义一个或多个LocalBuilder方法该方法被认为是该组件的私有、特殊类型的成员函数。自定义构建函数可以在所属组件的build方法和其他自定义构建函数中调用但不允许在组件外调用。在自定义函数体中this指代当前所属组件组件的状态变量可以在自定义构建函数内访问。建议通过this访问自定义组件的状态变量而不是参数传递。 三、限制条件 LocalBuilder只能在所属组件内声明不允许全局声明。LocalBuilder不能被内置装饰器和自定义装饰器使用。自定义组件内的静态方法不能和LocalBuilder一起使用。 四、LocalBuilder和局部Builder使用区别 Builder方法引用传参时为了改变this指向使用bind(this)后会导致组件的父子关系和状态管理的父子关系不一致但 LocalBuilder是否使用bind(this)都不会改变组件的父子关系。LocalBuilder和Builder区别说明。 五、参数传递规则 LocalBuilder函数的参数传递有按值传递和按引用传递两种均需遵守以下规则 参数的类型必须与参数声明的类型一致不允许undefined、null和返回undefined、null的表达式。在LocalBuilder修饰的函数内部不允许改变参数值。LocalBuilder内UI语法遵循UI语法规则。只有传入一个参数且参数需要直接传入对象字面量才会按引用传递该参数其余传递方式均为按值传递。 5.1 按引用传递参数 按引用传递参数时传递的参数可为状态变量且状态变量的改变会引起LocalBuilder方法内的UI刷新。 若子组件调用父组件的LocalBuilder函数传入的参数发生变化不会引起LocalBuilder方法内的UI刷新。 使用场景 组件TestLocalBuilder内的LocalBuilder方法在build函数内调用按键值对写法进行传值当点击Click me 时LocalBuilder内的Text文本内容会随着状态变量内容的改变而改变。 class ReferenceType {paramString: string ;
}Entry
Component
struct TestLocalBuilder {State variableValue: string Hello World;LocalBuilderciteLocalBuilder(params: ReferenceType) {Row() {Text(UseStateVarByReference: ${params.paramString} )}};build() {Column({ space: 10 }) {this.citeLocalBuilder({ paramString: this.variableValue });Button(Click me).onClick(() {this.variableValue Hi World;})}.padding(20)}
}效果图 按引用传递参数时如果在LocalBuilder方法内调用自定义组件ArkUI提供$$作为按引用传递参数的范式。 使用场景 组件TestLocalBuilder1内的LocalBuilder方法内调用自定义组件且按照引用传递参数将值传递到自定义组件当Parent组件内状态变量值发生变化时LocalBuilder方法内的自定义组件HelloComponent的message值也会发生变化。 class ReferenceType2 {paramString: string ;
}Component
struct HelloComponent22 {Prop message: string;build() {Row() {Text(HelloComponent${this.message});}}
}Entry
Component
struct TestLocalBuilder2 {State variableValue: string Hello World;LocalBuilderciteLocalBuilder($$: ReferenceType2) {Row() {Column() {Text(citeLocalBuilder${$$.paramString});HelloComponent22({ message: $$.paramString });}}}build() {Column({ space: 10 }) {this.citeLocalBuilder({ paramString: this.variableValue });Button(Click me).onClick(() {this.variableValue Hi World;})}}
}效果图 子组件引用父组件的LocalBuilder函数传入的参数为状态变量状态变量的改变不会引发LocalBuilder方法内的UI刷新原因是Localbuilder装饰的函数绑定在父组件上状态变量刷新机制是刷新本组件以及其子组件对父组件无影响故无法引发刷新。若使用Builder修饰则可引发刷新原因是Builder改变了函数的this指向此时函数被绑定到子组件上故能引发UI刷新。 使用场景 组件Child将State修饰的label值按照函数传参方式传递到Parent的Builder和LocalBuilder函数内在被Builder修饰的函数内this指向Child参数变化能引发UI刷新在被LocalBuilder修饰的函数内this指向Parent参数变化不能引发UI刷新。 class LayoutSize3 {size:number 0;
}Entry
Component
struct TestLocalBuilder3 {label:string parent;State layoutSize:LayoutSize3 {size:0};LocalBuilder// BuildercomponentBuilder($$:LayoutSize3) {Text(${this :this.label});Text(${size :$$.size});}build() {Column() {Child33({contentBuilder: this.componentBuilder });}}
}Component
struct Child33 {label:string child;BuilderParam contentBuilder:((layoutSize: LayoutSize3) void);State layoutSize:LayoutSize3 {size:0};build() {Column() {this.contentBuilder({size: this.layoutSize.size});Button(add child size).onClick((){this.layoutSize.size 1;})}}
}效果图 使用Builder参数变化可以引发UI刷新 六、按值传递参数 调用LocalBuilder装饰的函数默认按值传递。当传递的参数为状态变量时状态变量的改变不会引起LocalBuilder方法内的UI刷新。所以当使用状态变量的时候推荐使用按引用传递。 使用场景 组件Parent将State修饰的label值按照函数传参方式传递到LocalBuilder函数内此时LocalBuilder函数获取到的值为普通变量值所以改变State修饰的label值时LocalBuilder函数内的值不会发生改变。 Entry
Component
struct TestLocalBuilder4 {State label: string Hello;LocalBuilderciteLocalBuilder(paramA1: string) {Row() {Text(UseStateVarByValue: ${paramA1} )}}build() {Column({space: 10}) {this.citeLocalBuilder(this.label);Button(点击改变State修饰的label值).onClick((){this.label word;console.log(点击 改变State修饰的label值 this.label ${ this.label});})}}
}效果图 七、LocalBuilder和Builder区别说明 函数componentBuilder被Builder修饰时显示效果是 “Child”函数componentBuilder被LocalBuilder修饰时显示效果是“Parent”。 说明 Builder componentBuilder()通过this.componentBuilder的形式传给子组件BuilderParam customBuilderParamthis指向在Child的label即“Child”。 LocalBuilder componentBuilder()通过this.componentBuilder的形式传给子组件BuilderParam customBuilderParamthis指向Parent的label即“Parent”。 Component
struct Child5 {label: string Child5;BuilderParam customBuilderParam: () void;build() {Column() {this.customBuilderParam()}}
}Entry
Component
struct TestLocalBuilder5 {label: string Parent;Builder componentBuilder() {Text(${this.label})}// LocalBuilder componentBuilder() {// Text(${this.label})// }build() {Column() {Child5({ customBuilderParam: this.componentBuilder })}}
}函数componentBuilder被Builder修饰时显示效果是 “Child”效果图 函数componentBuilder被LocalBuilder修饰时显示效果是“Parent”效果图 八、使用场景 LocalBuilder在ComponentV2修饰的自定义组件中使用 使用局部的LocalBuilder在ComponentV2修饰的自定义组件中调用修改变量触发UI刷新。 ObservedV2
class Info6 {Trace name: string ;Trace age: number 0;
}ComponentV2
struct ChildPage6 {Require Param childInfo: Info6;build() {Column() {Text(自定义组件 name :${this.childInfo.name}).fontSize(20).fontWeight(FontWeight.Bold)Text(自定义组件 age :${this.childInfo.age}).fontSize(20).fontWeight(FontWeight.Bold)}}
}Entry
ComponentV2
struct TestLocalBuilder6 {info1: Info { name: Tom, age: 25 };Local info2: Info { name: Tom, age: 25 };LocalBuilderprivateBuilder() {Column() {Text(局部LocalBuilderBuilder name :${this.info1.name}).fontSize(20).fontWeight(FontWeight.Bold)Text(局部LocalBuilderBuilder age :${this.info1.age}).fontSize(20).fontWeight(FontWeight.Bold)}}LocalBuilderprivateBuilderSecond() {Column() {Text(局部LocalBuilderBuilder name :${this.info2.name}).fontSize(20).fontWeight(FontWeight.Bold)Text(局部LocalBuilderBuilder age :${this.info2.age}).fontSize(20).fontWeight(FontWeight.Bold)}}build() {Column() {Text(info1: ${this.info1.name} ${this.info1.age}) // Text1.fontSize(30).fontWeight(FontWeight.Bold)this.privateBuilder() // 调用局部BuilderLine().width(100%).height(10).backgroundColor(#000000).margin(10)Text(info2: ${this.info2.name} ${this.info2.age}) // Text1.fontSize(30).fontWeight(FontWeight.Bold)this.privateBuilderSecond() // 调用局部BuilderLine().width(100%).height(10).backgroundColor(#000000).margin(10)Text(info1: ${this.info1.name} ${this.info1.age}) // Text1.fontSize(30).fontWeight(FontWeight.Bold)ChildPage6({ childInfo: this.info1}) // 调用自定义组件Line().width(100%).height(10).backgroundColor(#000000).margin(10)Text(info2: ${this.info2.name} ${this.info2.age}) // Text2.fontSize(30).fontWeight(FontWeight.Bold)ChildPage6({ childInfo: this.info2}) // 调用自定义组件Line().width(100%).height(10).backgroundColor(#000000).margin(10)Button(change info1info2).onClick(() {this.info1 { name: Cat, age: 18} // Text1不会刷新原因是没有装饰器修饰监听不到值的改变。this.info2 { name: Cat, age: 18} // Text2会刷新原因是有装饰器修饰可以监听到值的改变。})}}
}效果图