HarmonyOS 鸿蒙Next 局部@Builder传参问题

发布于 1周前 作者 bupafengyu 最后一次编辑是 5天前 来自 鸿蒙OS

HarmonyOS 鸿蒙Next 局部@Builder传参问题

 遇到的问题是 

Num1,Num2,Num3,这三个参数按照下面的方法写的话,能在Badge里面显示

但是在实际情况中,这三个参数是通过接口返回的,并在aboutToAppear中能打印出数据,也是在aboutToAppear中重新获取的数据,但是这样写的Badge就不会显示数据

// xxx.ets
@Entry
@Component
struct TabsExample {
  @State fontColor: string = '#182431'
  @State selectedFontColor: string = '#007DFF'
  @State currentIndex: number = 0
  @State selectedIndex: number = 0
  private controller: TabsController = new TabsController()
  @State Num1:number=9
  @State Num2:number=59
  @State Num3:number=109

  [@Builder](/user/Builder) tabBuilder(index: number, name: string,num:number) {
    Column() {
      Badge({
        count:num,
        style: { fontSize: 10, badgeSize: 1 },
        position: { x: 10, y: -10 },
      }){
        Text(name)
          .fontColor(this.selectedIndex === index ? this.selectedFontColor : this.fontColor)
          .fontSize(16)
          .fontWeight(this.selectedIndex === index ? 500 : 400)
          .lineHeight(22)
      }

      Divider()
        .strokeWidth(2)
        .color('#007DFF')
        .opacity(this.selectedIndex === index ? 1 : 0)
    }.width('100%')
  }
  [@Builder](/user/Builder) TabsBuilder(){
    Tabs({ barPosition: BarPosition.Start, index: this.currentIndex, controller: this.controller }) {
      TabContent() {
        Column().width('100%').height('100%').backgroundColor('#00CB87')
      }.tabBar(this.tabBuilder(0, 'green',this.Num1))

      TabContent() {
        Column().width('100%').height('100%').backgroundColor('#007DFF')
      }.tabBar(this.tabBuilder(1, 'blue',this.Num2))

      TabContent() {
        Column().width('100%').height('100%').backgroundColor('#FFBF00')
      }.tabBar(this.tabBuilder(2, 'yellow',this.Num3))

    }
    .vertical(false)
    .barMode(BarMode.Fixed)
    .barWidth(360)
    .barHeight(56)
    .animationDuration(400)
    .onChange((index: number) => {
      // currentIndex控制TabContent显示页签
      this.currentIndex = index
    })
    .onAnimationStart((index: number, targetIndex: number, event: TabsAnimationEvent) => {
      if (index === targetIndex) {
        return
      }
      // selectedIndex控制自定义TabBar内Image和Text颜色切换
      this.selectedIndex = targetIndex
    })
    .width(360)
    .height(296)
    .margin({ top: 52 })
    .backgroundColor('#F1F3F5')
  }

  build() {
    Column() {
this.TabsBuilder()
    }.width('100%')
  }
}
3 回复

@Builder修饰的方法只有当传递参数只有一个时,才是按引用传递,其他是按值传递,因此不能响应数据变化,
以你的代码为例:

interface temp {
 index: number,
 name: string,
 num: number
}

[@Entry](/user/Entry)
[@Component](/user/Component)
struct BuilderTest {
 // xxx.ets
 [@State](/user/State) fontColor: string = '#182431'
 [@State](/user/State) selectedFontColor: string = '#007DFF'
 [@State](/user/State) currentIndex: number = 0
 [@State](/user/State) selectedIndex: number = 0
 private controller: TabsController = new TabsController()
 [@State](/user/State) Num1: number = 9
 [@State](/user/State) Num2: number = 59
 [@State](/user/State) Num3: number = 109

 [@Builder](/user/Builder)
 tabBuilder(temp: temp) {
   Column() {
     Badge({
       count: temp.num,
       style: { fontSize: 10, badgeSize: 1 },
       position: { x: 10, y: -10 },
     }) {
       Text(temp.name)
         .fontColor(this.selectedIndex === temp.index ? this.selectedFontColor : this.fontColor)
         .fontSize(16)
         .fontWeight(this.selectedIndex === temp.index ? 500 : 400)
         .lineHeight(22)
     }

     Divider()
       .strokeWidth(2)
       .color('#007DFF')
       .opacity(this.selectedIndex === temp.index ? 1 : 0)
   }.width('100%')
 }

 [@Builder](/user/Builder)
 TabsBuilder() {
   Tabs({ barPosition: BarPosition.Start, index: this.currentIndex, controller: this.controller }) {
     TabContent() {
       Column() {
         Button("控制blue数字").onClick(() => {
           this.Num2++
         })
       }.width('100%').height('100%').backgroundColor('#00CB87')
     }.tabBar(this.tabBuilder({
       index: 0,
       name: 'green',
       num: this.Num1
     }))

     TabContent() {
       Column() {
         Button("控制yellow数字").onClick(() => {
           this.Num3++
         })
       }.width('100%').height('100%').backgroundColor('#007DFF')
     }.tabBar(this.tabBuilder({
       index: 1,
       name: 'blue',
       num: this.Num2
     }))

     TabContent() {
       Column() {
         Button("控制green数字").onClick(() => {
           this.Num1++
         })
       }.width('100%').height('100%').backgroundColor('#FFBF00')
     }.tabBar(this.tabBuilder({
       index: 2,
       name: 'yellow',
       num: this.Num3
     }))

   }
   .vertical(false)
   .barMode(BarMode.Fixed)
   .barWidth(360)
   .barHeight(56)
   .animationDuration(400)
   .onChange((index: number) => {
     // currentIndex控制TabContent显示页签
     this.currentIndex = index
   })
   .onAnimationStart((index: number, targetIndex: number, event: TabsAnimationEvent) => {
     if (index === targetIndex) {
       return
     }
     // selectedIndex控制自定义TabBar内Image和Text颜色切换
     this.selectedIndex = targetIndex
   })
   .width(360)
   .height(296)
   .margin({ top: 52 })
   .backgroundColor('#F1F3F5')
 }

 build() {
   Column() {
     this.TabsBuilder()
   }.width('100%')
 }
}

关于HarmonyOS 鸿蒙Next 局部@Builder传参问题,以下是一些专业解答:

在HarmonyOS 鸿蒙Next中,@Builder修饰的函数参数传递有按值传递和按引用传递两种方式。参数类型必须与声明类型一致,不允许undefined、null或返回这些值的表达式。在@Builder函数内部,不允许改变参数值。仅当传入一个参数且为对象字面量时,才会按引用传递,其余方式均按值传递。

若需在@Builder方法内调用自定义组件或其他@Builder方法,并希望参数按引用传递,HarmonyOS提供了$$作为传递参数的范式。在@Builder方法中,this通常指代当前所属组件,因此可以访问组件的状态变量。但要注意,在某些嵌套或复杂场景下,this的指向可能会发生变化,需特别小心处理。

此外,@BuilderParam装饰器用于装饰自定义组件中的属性,使其可以作为UI结构的占位符。在创建组件时,可以通过参数为其传入具体的内容。

如果在使用@Builder时遇到具体的参数问题,且上述解答无法直接解决,请检查参数的类型、传递方式以及this的指向是否正确。如果问题依旧没法解决请联系官网客服,官网地址是:https://www.itying.com/category-93-b0.html

回到顶部