@Builder和@BuilderParam的实战使用,封装自定义通用导航栏

一.@Builder,@BuilderParam的简要介绍

1.@Builder装饰器:自定义构建函数

  • 允许在自定义组件内定义一个或多个@Builder方法,该方法被认为是该组件的私有、特殊类型的成员函数。

  • 自定义构建函数可以在所属组件的build方法和其他自定义构建函数中调用,但不允许在组件外调用。

  • 在自定义函数体中,this指代当前所属组件,组件的状态变量可以在自定义构建函数内访问。建议通过this访问自定义组件的状态变量而不是参数传递。

@Builder可以在组件内定义,也可定义全局自定义构建函数:

/**
*全局定义函数,注意添加function关键字标识
*如果不涉及组件状态变化,建议使用全局的自定义构建方法。
*/
@Builder function MyGlobalBuilderFunction() { ... }
//使用方法
MyGlobalBuilderFunction()

/**
*自定义组件内自定义构建函数
*/
@Builder MyBuilderFunction() { ... }
//使用方法(使用this关键字指向)
this.MyBuilderFunction()

2.@BuilderParam装饰器:引用@Builder函数

       开发者创建了自定义组件,并想对该组件添加特定功能时,例如在自定义组件中添加一个点击跳转操作。若直接在组件内嵌入事件方法,将会导致所有引入该自定义组件的地方均增加了该功能。为解决此问题,ArkUI引入了@BuilderParam装饰器,@BuilderParam用来装饰指向@Builder方法的变量(@BuilderParam是用来承接@Builder函数的),开发者可在初始化自定义组件时对此属性进行赋值,为自定义组件增加特定的功能。该装饰器用于声明任意UI描述的一个元素,类似slot占位符

/**
*以下示例中,Parent组件在调用this.componentBuilder()时,this指向其所属组件,即“Parent”。*@Builder componentBuilder()通过this.componentBuilder的形式传给子组件@BuilderParam *customBuilderParam,this指向在Child的label,即“Child”。@Builder componentBuilder()
*通过 ():void=>{this.componentBuilder()}的形式传给子组件@BuilderParam *customChangeThisBuilderParam,因为箭头函数的this指向的是宿主对象,所以label的值为“Parent”。
*/
@Component
struct Child {
  label: string = `Child`
  @Builder customBuilder() {}
  @Builder customChangeThisBuilder() {}
  @BuilderParam customBuilderParam: () => void = this.customBuilder;
  @BuilderParam customChangeThisBuilderParam: () => void = this.customChangeThisBuilder;

  build() {
    Column() {
      //注意加上(),编译器不加()也会通过,但是无法生效。
      this.customBuilderParam()
      this.customChangeThisBuilderParam()
    }
  }
}

@Entry
@Component
struct Parent {
  label: string = `Parent`

  @Builder componentBuilder() {
    Text(`${this.label}`)
  }

  build() {
    Column() {
      this.componentBuilder()
      Child({ customBuilderParam: this.componentBuilder, customChangeThisBuilderParam: ():void=>{this.componentBuilder()} })
    }
  }
}

二.自定义封装全局通用导航栏

封装:

// NavigationBar.ets

/**
 * 自定义通用导航栏
 */
@Component
export struct NavigationBar {
  @Prop title: String;

  @Builder buttonBack(){}
  @Builder menuOne(){}
  @Builder menuTwo(){}
  @Builder menuThree(){}
  @BuilderParam buildButtonBackParam:()=> void = this.buttonBack
  @BuilderParam buildMenuOneParam:()=> void = this.menuOne
  @BuilderParam buildMenuTwoParam:()=> void = this.menuTwo

  @BuilderParam buildMenuThreeParam:()=> void = this.menuThree

  build() {
    Flex({ direction: FlexDirection.Row, justifyContent: FlexAlign.SpaceBetween }) {
      Row() {
        this.buildButtonBackParam()
      }.margin({left:15})

      //水平绝对居中
      Text(this.title + "")
        .position({left:'50%'}).translate({x:'-50%'})
        .lineHeight(25)

      Row({space:5}){
        this.buildMenuOneParam()
        this.buildMenuTwoParam()
        this.buildMenuThreeParam()
      }
      .height('100%').margin({right:15})
    }
    .width('100%')
    .height(25)
    .margin({top:10})
  }
}

调用使用:

import {NavigationBar} from '../ets/common/components/NavigationBar'
//全局的自定义函数
@Builder function buildBackButton(){
    Button({ type: ButtonType.Normal, stateEffect: false }) {
      Image($r('app.media.down'))
    }
    .width(25).height(25).borderRadius(50)
    .backgroundColor('rgba(255,255,255,0)')
  }

@Entry
@Component
struct Parent {
  //图片资源换成自己的就好,放入resource/base/media下就行
  @Builder buildOneMenu(){
    Button({ type: ButtonType.Normal, stateEffect: false }) {
      Image($r('app.media.more_one'))
    }
    .width(25).height(25).borderRadius(50)
    .backgroundColor('rgba(255,255,255,0)')
  }

  @Builder buildTwoMenu(){
    Button({ type: ButtonType.Normal, stateEffect: false }) {
      Image($r('app.media.search'))
    }
    .width(25).height(25).borderRadius(50)
    .backgroundColor('rgba(255,255,255,0)')
  }
  @Builder buildThreeMenu(){
    Button({ type: ButtonType.Normal, stateEffect: false }) {
      Image($r('app.media.preview_open'))
    }
    .width(25).height(25).borderRadius(50)
    .backgroundColor('rgba(255,255,255,0)')
  }

  build() {
    Column() {
      NavigationBar({title:"标题一"
      ,buildButtonBackParam:buildBackButton
      ,buildMenuOneParam:():void=>{this.buildOneMenu()}//this的指向是当前父页面
      ,buildMenuTwoParam:this.buildTwoMenu
      })

      NavigationBar({title:"标题二"
      ,buildButtonBackParam:buildBackButton
      ,buildMenuOneParam:():void=>{this.buildOneMenu()}
      ,buildMenuTwoParam:this.buildTwoMenu
      ,buildMenuThreeParam:this.buildThreeMenu
      })
    }
  }
}

效果图:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值