鸿蒙开发:5-鸿蒙中的slot-@Builder自定义构建函数

219 阅读2分钟

鸿蒙中的slot-@Builder自定义构建函数

在封装组件的时候,我们有时需要传入一些自定义的UI内容,相当于在组件中添加插槽,在鸿蒙中如何实现呢?我们可以使用@Builder来实现。

@Builder:装饰自定义构建函数,其实就是一段轻量的UI。

下面以封装一个头部NavBar组件为例:

1、在子组件中定义一个@BuilderParam

image.png

2、在父组件中传入UI内容

image.png

3、效果

image.png

4、注意的点

  1. 上例父组件中定义的titleBuilder自定义构建函数为局部函数(在父组件内),仅能在父组件中使用,如果要在不同组件中使用,可以定义在组件外,成为全局自定义构建函数。
  2. 组件内的自定义构建函数(后面简称函数),函数内可以访问所在组件的所有状态变量和函数。
  3. 注意this指向,在给子组件传递函数时,使用箭头函数,或者bind(this)来绑定父组件作用域,如果直接传递函数名,则函数内的this会指向子组件(其渲染的地方)。如下图:

image.png

5、完整代码

父组件:

import { NavBar } from '../components/NavBar';

@Entry
@Component
struct Index3 {
  @State title: string = '炸天科技';

  @Builder
  titleBuilder() {
    Image($r('app.media.app_icon'))
      .width('24vp')
      .height('24vp')
    Text(this.title)
      .fontSize('30vp')
      .fontColor(Color.Red)
      .margin({ left: '10vp' })
      .onClick(() => {
        this.title = '嘿嘿嘿';
      })
  }

  build() {
    Column() {
      NavBar({ title: '测试标题' })
      NavBar({
        titleBuilder: () => {
          this.titleBuilder();
        }
      })
    }
  }
}

子组件:

import { router } from '@kit.ArkUI';

@Component
export struct NavBar {
  @Prop title?: string = ''

  @Builder
  TitleBuilder() {
  }

  @BuilderParam
  titleBuilder: () => void = this.TitleBuilder;

  build() {
    Row() {
      Column() {
        Text('<')
          .fontColor('#000')
          .fontSize('30vp')
      }
      .width('40vp')
      .onClick(() => {
        router.back();
      })

      Row() {
        if (this.title) {
          Text(this.title)
            .fontSize('30vp')
            .fontColor('#000')
        } else {
          this.titleBuilder();
        }
      }
      .justifyContent(FlexAlign.Center)
      .flexGrow(1)

      //其他业务预留
      Row() {
      }
      .width('40vp')
      .backgroundColor(Color.Yellow)
    }
    .width('100%')
    .height('50vp')
    .padding({ left: '20vp', right: '20vp' })
    .backgroundColor('#efefef')
  }
}

如果觉得对你有帮助,点个赞呗!!!