HarmonyOS 鸿蒙Next中关于@builder中使用$$的问题

HarmonyOS 鸿蒙Next中关于@builder中使用$$的问题

页面中有多个类似的UI,如:

标题: [输入框]
标题: [输入框]

标题: [输入框]

于是我想把这每一行封装一下,方便直接调用,但是又不想把他单独封装成一个组件(本身太过简单,封装组件不合适)
于是就想着用@builder进行轻量封装:

试图这样通过$$双向绑定变量,但是实际上TextInput({text: $$content})这里会报错,那应该怎么改才能让他正常运行???难道只能封装成子组件吗?

@state content1:string = ''
@state content2:string = ''
@state content3:string = ''

build() {
  Column() {
    this.getItem('字段名1', $$this.content1)
    this.getItem('字段名2', $$this.content2)
    this.getItem('字段名3', $$this.content3)
  }
  .width('100%')
}

@Builder
getItem(title:string, content:string){
  Text(title)
  ...各种属性设置
  TextInput({text: $$content})
  ...各种属性设置
}

更多关于HarmonyOS 鸿蒙Next中关于@builder中使用$$的问题的实战教程也可以访问 https://www.itying.com/category-93-b0.html

6 回复

当直接在@Builder函数内使用$$进行双向绑定时,由于ArkUI的编译时作用域限制,@Builder无法直接访问父组件的@State变量。需要显式传递绑定参数来实现双向绑定。

[@Builder](/user/Builder) function InputLine(title: string, content: $$string) {
  Flex({ justifyContent: FlexAlign.SpaceBetween }) {
    Text(title).fontSize(16)
    TextInput({ text: content })
      .width('60%')
      .backgroundColor(Color.White)
  }
}

// 父组件调用
@Component
struct MyPage {
  [@State](/user/State) input1: string = ''
  [@State](/user/State) input2: string = ''

  build() {
    Column() {
      this.InputLine('标题1', $$this.input1)
      this.InputLine('标题2', $$this.input2)
    }
  }
}
  • 通过参数显式传递$$绑定变量
  • 需用this.xxx调用类内的@Builder函数

更多关于HarmonyOS 鸿蒙Next中关于@builder中使用$$的问题的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


项目名称

  • 状态:进行中
  • 开始时间:2023-02-01
  • 结束时间:2023-04-01

成员

  • 张三
  • 李四
  • 王五

进度

  • 需求分析完成
  • 设计稿确认
  • 前端开发进行中
  • 后端开发待开始

可以用V2

@Entry
@ComponentV2
struct Index {
  @Local content1: string = '1'
  @Local content2: string = '2'
  @Local content3: string = '3'
  @Local message: string = '';

  build() {
    Column({ space: 10 }) {
      Item({ title: '字段名1', content: this.content1!! })
      Item({ title: '字段名2', content: this.content2!! })
      Item({ title: '字段名3', content: this.content3!! })
      Row() {
        Text(`结果`).width('16%')
        Text(`${this.message}`).width('76%')
      }.height(40)

      Button(`提交`).onClick(() => {
        this.message = this.content1!! + "  " + this.content2!! + "  " + this.content3!!
      })
    }.margin(10)
    .width('100%')
    .height('100%')
  }
}

@ComponentV2
struct Item {
  @Param title: string = '';
  @Param content: string = '';
  @Event $content: (val: string) => void = (val: string) => {
  };

  build() {
    Row() {
      Text(`${this.title}`).width('16%')
      TextInput({ text: this.content }).width('76%')
        .onChange((value: string) => {
          this.$content(value);
        })
    }
  }
}

在鸿蒙Next中,@builder装饰器结合$$语法用于动态构建UI组件。$$表示双向绑定,当状态变量变化时自动更新UI。在@builder中使用$$时,需确保绑定的变量是@State@Link等装饰的响应式数据。例如:

@Builder function MyBuilder($$: { count: number }) {
  Text(`Count: ${$$.count}`)
}

@Entry
@Component
struct MyComponent {
  @State count: number = 0

  build() {
    Column() {
      MyBuilder({ count: $$this.count })
      Button('Add').onClick(() => this.count++)
    }
  }
}

注意$$通过解构传递参数,直接绑定到响应式变量。

在HarmonyOS Next中,@Builder装饰器内直接使用$$双向绑定确实会报错,因为Builder函数参数不支持这种语法。建议改用以下两种方案:

  1. 使用回调函数方式传递值:
[@Builder](/user/Builder)
getItem(title:string, content:string, onChange:(value:string)=>void){
  Text(title)
  TextInput({text: content})
    .onChange((value: string) => {
      onChange(value)
    })
}
  1. 如果确实需要双向绑定,可以将简单UI封装为@Component组件:
[@Component](/user/Component)
struct InputItem {
  @Link content: string
  title: string

  build() {
    Column() {
      Text(this.title)
      TextInput({text: $$this.content})
    }
  }
}

这两种方式都能实现需求,第一种更轻量,第二种更符合HarmonyOS的响应式设计规范。

回到顶部