1、自定义构建函数
1.1、构建函数- @Builder
如果你不想在直接抽象组件,ArkUI还提供了一种更轻量的UI元素复用机制 @Builder,可以将重复使用的UI元素抽象成一个方法,在 build 方法里调用。称之为自定义构建函数
- 用法- 使用@Builder修饰符修饰
1.1.1、全局自定义 @Builder function name () {}
全局自定义函数指在struct外面的函数
@Builder
function getCellContent(leftTitle: string, rightValue: string) { // 全局自定义函数带function
Row() {
Row() {
Text(leftTitle)
Text(rightValue)
}
.width('100%')
.justifyContent(FlexAlign.SpaceBetween)
.padding({
left: 15,
right: 15
})
.borderRadius(8)
.height(40)
.backgroundColor(Color.White)
}.padding({
left: 10,
right: 10
})
}
在组件中使用
Column({space:10}) {
getCellContent("时间", "2023-12-12")
getCellContent("位置", "上海")
getCellContent("爱好", "乒乓")
}
全局自定义函数的问题
● 全局的自定义构建函数可以被整个应用获取(下一代可用-当前4.0暂不支持),不允许使用this和bind方法。
● 如果不涉及组件状态变化,建议使用全局的自定义构建方法。
● 补一句-如果数据是响应式的-此时该函数不会自动渲染-哪怕是全局自定义函数,不可被其他文件引用
将数据声明为State响应式数据
class CardClass {
time: string = ""
location: string = ""
type: string = ""
}
@State formData: CardClass = {
time: "2023-12-12",
location: '回龙观',
type: '漏油'
}
传递数据,绑定为对应字段
Column({ space: 10 }) {
getCellContent("异常时间", this.formData.time)
getCellContent("异常位置", this.formData.location)
getCellContent("异常类型", this.formData.type)
Button("修改数据").onClick(() => {
this.formData.location = "望京"
})
}
.width('100%')
我们发现,点击修饰是没有任何反应的,说明此时即使你用了State,但是此时的全局builder依然不更新
1.1.2、组件内定义- 语法 @Builder name () {}
@Entry
@Component
struct BuilderCase {
@Builder
getCellContent(leftTitle: string, rightValue: string) { // 组件内自定义函数不带function
}
}
调用
this.getCellContent("异常时间", this.formData.time)
调用多了this,其他和全局属性一样,没有任何变化,此时我们发现修改数据依然没有任何变化
注意: 我们刚刚传过去的是类型,string是一个基础数据类型,它是按值传递的,不具备响应式更新的特点
总结
- 全局Builder函数和组件Builder构建函数可以实现一种轻量级的UI复用,
- 区别: 全局自定义构建函数不允许使用this,bind,它适合一种纯渲染的UI结构;组件内自定义Builder可以实现this调用
1.2、参数传递
自定义构建函数的参数传递有按值传递和按引用传递两种,均需遵守以下规则:
- 参数的类型必须与参数声明的类型一致,不允许undefined、null和返回undefined、null的表达式。
- 在自定义构建函数内部,不允许改变参数值。如果需要改变参数值,且同步回调用点,建议使用@Link。
- @Builder内UI语法遵循UI语法规则。
- 只有传入一个参数,且参数需要直接传入对象字面量才会按引用传递该参数,其余传递方式均为按值传递。
1)、使用了string这种基础数据类型,即使它属于用State修饰的变量,也不会引起UI的变化
2)、按引用传递参数时,传递的参数可为状态变量,且状态变量的改变会引起@Builder方法内的UI刷新。ArkUI提供$$作为按引用传递参数的范式。
ABuilder( $$ : 类型 );
函数名称( obj: 类型 );
3)、也就是我们需要在builder中传入一个对象, 该对象使用$$(可使用其他字符)的符号来修饰,此时数据具备响应式了
@Entry
@Component
struct BuilderCase {
@State formData: CardClass = { // state修饰的状态变量
time: "2023-12-12",
location: '回龙观',
type: '漏油'
}
@Builder
getCellContent($$: CellParams) { // 传入一个对象,$$可以为任意字符
Row() {
Row() {
Text($$.leftTitle)
Text($$.rightValue)
}
.width('100%')
.justifyContent(FlexAlign.SpaceBetween)
.padding({
left: 15,
right: 15
})
.borderRadius(8)
.height(40)
.backgroundColor(Color.White)
}.padding({
left: 10,
right: 10
})
}
build() {
Row() {
Column() {
Column({ space: 10 }) {
this.getCellContent({ leftTitle: '异常时间', rightValue: this.formData.time }) // 传入一个对象,且有state修饰符修饰的变量
this.getCellContent({ leftTitle: '异常位置', rightValue: this.formData.location }) // 传入一个对象,且有state修饰符修饰的变量
this.getCellContent({ leftTitle: '异常类型', rightValue: this.formData.type })
}
.width('100%')
Button("修改数据").onClick(() => {
this.formData.location = "望京" // 修改state修改是的对象的属性,可以导致UI更新
})
}
.width('100%')
}
.height('100%')
.backgroundColor('#ccc')
}
}
● 使用 @Builder 复用逻辑的时候,支持传参可以更灵活的渲染UI
● 参数可以使用状态数据,通过对象的方式传入 @Builder
网友评论