此文章内容兼容API12,使用harmony next应用开发
@Builder
1,使用说明
- 组件内部使用,此时是私有的组件构建函数装饰器
- 全局使用
2,参数
(1)传参包括 值传递、引用传递两种方式
值传递。 此时哪怕传递状态变量,也不会引起UI刷新
引用传递 (对象字面量的形式),可以引起UI刷新
对象字面量:对象字面量是一个名值对列表,每个名值对之间用逗号分隔,并用一个大括号括起。各名值对表示对象的一个属性,名和值这两部分之间用一个冒号分隔,并且使用的时候不需要使用new关键字
var item={name: "tom", value:123}
@State buildTest:string = 'hey'
@Builder
BuildView() {
Button('改变值')
.onClick(() => this.buildTest = 'change')
this.BuildParam1View(this.buildTest)//值传递
this.BuildParam2View({param1:this.buildTest})//引用传递:对象字面量的形式
}
@Builder
BuildParam1View(str:string) {
Text(`值传递:${str}`) //不会刷新
}
@Builder
BuildParam2View(clazz:BuildClazz) {
Text(`引用传递:${clazz.param1}`)//会刷新
}
}
class BuildClazz{
param1 : string = 'BuildClazz'
}
(2)刷新说明
- 仅在 引用传递时,且只有一个参数时,才会触发UI;
- 引用传递,必须按照 对象字面量的形式,把所需属性一一传入,才会触发刷新
- 若同时存在 值传递、引用传递两种方式,无法触发UI更新;若同时传递两个或以上,无法触发UI更新
- 全局自定义 @Builder 组件,也可使用对象字面量形式的引用传递,触发刷新
3,嵌套
@Builder 内嵌套 @Builder 组件,或嵌套自定义组件,可以使用 $$ 范式
...{
...
this.BuildParam3View({param1:this.buildTest})
}
@Builder
BuildParam3View($$:BuildClazz) {
Text(`嵌套使用:${$$.param1}`)//会刷新
this.BuildParam3SonView($$)
}
@Builder
BuildParam3SonView($$:BuildClazz) {
Text(`嵌套使用(Son):${$$.param1}`)//会刷新
}
4,@Builder 函数 最好要被Column/Row(根节点)包裹,否则直接使用if函数时,无法创建出组件
@Builder
BuildParam3SonView() {
if(...){ Text(`test1`) }
else{ Text(`test2`) }
}
@LocalBuilder
引入 @LocalBuilder,解决自定义组件间的父子关系,确保状态管理时保持一致
1,区别
@Build | @LocalBuilder |
---|---|
可以再组件内声明,也可以全局声明 | 只能在组件内生命。 |
2,引用传递和值传递,效果场景都和 @Build 相同
@BuilderParam
用于扩展自定义组件。在使用自定义组件时,通过对 @BuilderParam 装饰的函数进行传参赋值等,为组件增加特定功能
类似于 slot 占位符
//自定义组件
...
@Builder
BuildParamView(){
//两种方式都可,但存在区别,见下文
BuildParamSonView({addHeader:() =>{this.BuildParamSonHeaderView()}})
BuildParamSonView({addHeader:this.BuildParamSonHeaderView})
}
@Builder BuildParamSonHeaderView(){
Text('我是 Header')
}
}
@Component
export struct BuildParamSonView{
@BuilderParam addHeader:()=>void
build() {
Column(){
this.addHeader()
}
}
}
1,使用说明
- 可将用@Builder修饰的自定义view,传递自定义组件中。使用 this. 方式引用
- 必须声明类型
- 可以结合@Require 使用,强制父组件传参
- 本地初始化,及引用处,只能传递 @Builder 构建的函数
2,两种传递方式的区别
...
@State label:string = '我是父'
@Builder
Parent(){
//此种方式,this 指代的是子组件Son,因此展示为 ‘我是子 | 创建Header ’
Son({addHeader:() =>{this.BuildView()}})
// 此种方式,this 指代的是宿主组件Parent,因此展示为 ‘我是父 | 创建Header '
Son({addHeader:this.BuildView})
}
@Builder BuildView(){
Text(this.label+" | 创建Header")
}
}
@Component
export struct Son{
@State label:string = '我是子'
@BuilderParam addHeader:()=>void
build() {
Column(){
this.addHeader()
}
}
}
3,与此同时,如果想宿主组件 Parent 的状态改变,同步到自定义组件Son中,需要使用 第一种方式,让this 指代宿主组件Parent
Son({addHeader:() =>{this.BuildView()}})
4,@BuilderParam 支持参数,但需和 @Builder 一致
@BuilderParam addHeader:( tmp : ClassA )=>void
@Style
@Builder 复用组件,@Style 复用样式
- @Style 仅支持通用属性,和 通用事件
- @Style 不支持参数
- @Style 可以定义在组件内或全局,但不能跨文件,更不能跨模块 ; 不能使用 export 关键字
- 组件内的 @Style 可访问组件的常量和状态变量
@Extend
用于扩展 原生组件 的样式
- @Extend 支持 私有属性
- @Extend 支持参数
- 仅支持全局定义,不能在组件内使用
- @Extend 参数支持 function,也可为状态变量
@Extend(Text) function makeMeClick(onClick: () => void) {
.backgroundColor(Color.Blue)
.onClick(onClick)
}
...
Text(`${this.label}`)
.makeMeClick(() => {this.onClickHandler()})
...
stateStyles
支持在不同状态下 ,样式变化。可和 @Style 联合使用
- focused:获焦态。
- normal:正常态。
- pressed:按压态。
- disabled:不可用态。
- selected10+:选中态。
1,仅支持通用属性
2,可使用组件内的变量
Button('Button1')
.stateStyles({
focused: {
.backgroundColor('#ffffeef0')
},
pressed: {
.backgroundColor('#ff707070')
},
normal: {
.backgroundColor('#ff2787d9')
}
})
//----------------- SPLIT LINE -----------------------
@Styles normalStyle() {
.backgroundColor(Color.Gray)
}
@Styles pressedStyle() {
.backgroundColor(Color.Red)
}
...
Button('Button1')
.stateStyles({
normal: this.normalStyle,
pressed: this.pressedStyle,
})
...
@AnimatableExtend
自定义可动画的属性方法
@Require
@Require 作用于父子之间, 用于校验自定义组件中, @Prop、@State、@Provide、@BuilderParam 修饰的变量,和普通变量,是否必须传参
@Require @State label: string = "Hello";