自定义构建函数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中的插槽

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  //下划线
      }
    })
  }
}
上一篇 下一篇

猜你喜欢

热点阅读