自定义构建函数2
2024-01-21 本文已影响0人
家乡的蝈蝈
1、自定义构建函数
1.1、构建函数- @BuilderParam 传递UI
● Component可以抽提组件
● Builder可以实现轻量级的UI复用
● BuilderParam只能应用在Component组件中,不能使用Entry修饰的组件中使用。类似vue里面的slot插槽
语法: @BuilderParam name: () => void
声明一个Card组件
@Component
struct Card {
@BuilderParam // 代表插槽的参数
content: () => void = () => {}
build() {
Column() {
if (this.content) {
this.content() // 渲染传入的内容
}
父组件调用传入
@Entry
@Component
struct BuilderParamCase {
@Builder // 定义插槽
getContent () {
Row() {
Text("插槽内容")
.fontColor(Color.Red)
}
}
build() {
Row() {
Column() {
// 需要注意的是,传入的函数必须是使用Builder修饰符修饰的
Card({ content: this.getContent }) // 调用子组件,并把插槽作为参数传入
}
.width('100%')
}
.height('100%')
}
}
BuilderParams类似于 Vue中的插槽
- 子组件中定义一个用BuilderParam修饰的函数
- 父组件需要给子组件传入一个用Builder修饰的函数来赋值给子组件
- 子组件要在想要显示插槽的地方来调用传入的方法
1.1.1、尾随闭包
当我们的组件只有一个BuilderParam的时候,此时可以使用尾随闭包的语法 也就是像我们原来使用Column或者Row组件时一样,直接在大括号中传入, 如下
Card() {
Text('1')
this.renderButton()
}
如果有多个BuilderParam,你必须在组件的函数中老老实实的传入多个builder自定义函数
@Component
struct Card {
@BuilderParam
content: () => void // 传入多个builder自定义函数
@BuilderParam
header: () => void // 传入多个builder自定义函数
build() {
Column () {
if(this.header) {
this.header()
}
if(this.content) {
this.content()
}
}
}
}
@Entry
@Component
struct BuilderParamCase {
@Builder
getContent () {
Row() {
Text("插槽内容")
.fontColor(Color.Red)
}
}
@Builder
getHeader () {
Row() {
Text("头部内容")
.fontColor(Color.Red)
}
}
build() {
Row() {
Column() {
Card({
header: () => { // 传入多个builder自定义函数
this.getHeader()
},
content: () => { // 传入多个builder自定义函数
this.getContent()
}
})
}
.width('100%')
}
.height('100%')
}
}
案例- 封装Card 和CardItem组件, 使用BuilderParam属性完成插槽传参
@Entry
@Component
struct BuildParamCard {
@State message: string = 'Hello World'
@Builder
getCardItem() {
CardItem({leftTitle:'员工姓名', rightTitle:'张三'})
CardItem({leftTitle:'员工上级', rightTitle:'李四', showBottomBorder:false})
}
build() {
Row() {
Column() {
Card2({CardFn:this.getCardItem})
}
.width('100%')
}
.height('100%')
.backgroundColor(Color.Gray)
}
}
@Component
struct Card2 {
@BuilderParam
CardFn: () => void = () => {}
build() {
Column() {
Column() {
// 传插槽内容
this.CardFn()
}
.backgroundColor(Color.White)
.width('100%')
.borderRadius(8)
}.margin({
top:10
})
.padding({
left:15,
right:15
})
}
}
@Component
struct CardItem {
leftTitle:string = ""
rightTitle:string = ""
showBottomBorder:boolean = true
build() {
Row() {
Text(this.leftTitle)
Text(this.rightTitle).fontColor("#ccc")
}
.width('100%')
.justifyContent(FlexAlign.SpaceBetween)
.padding({
left:10,
right:10
})
.height(50)
.border({
color:'#f4f5f6',
width:{
bottom:this.showBottomBorder ? 1 :0 //下划线
}
})
}
}