自定义组件、@BuilderParam、@State、@Prop

327 阅读3分钟

自定义组件、@BuilderParam、@State、@Prop

一、自定义组件基础

作用:在ArkUI中,UI显示的内容均为组件,由框架直接提供的称为系统组件,由开发者定义的称为自定义组件。

1.1、基本使用

基础语法:

// 定义
@Component
struct MyComponent {
  // 状态变量
  @State message:string =''
  build(){
    // .... 描述 UI
  }
}


//----------使用-----------

// 1.不传递参数使用
// MyComponent() 

// 2.传递参数使用:通过传递参数的方式 设置子组件中 messsage 的值
// MyComponent({message:'xxx'})

注意:自定义组件名、类名、函数名不能和系统组件名相同。

代码演示:

@Component
struct MyButton {
  title:string = '点击'
  bgColor:string = '#00ff00'
  build() {
    Row() {
      Button(this.title)
        .type(ButtonType.Normal)
        .borderRadius(3)
        .backgroundColor(this.bgColor)
      Text()
        .width(10)
        .height(10)
        .backgroundColor(this.bgColor)
        .translate({ x: -5 })
        .rotate({ angle: 45 })
    }
    }
}
@Entry
@Component
struct zy {
  build() {
    Column(){
      MyButton({title:'登录',bgColor:'#ff00'})
      MyButton()
    }
    .width('100%')
    .height('100%')
  }
}

效果图:

image.png

1.2、 成员函数/变量

作用:自定义组件除了必须要实现build()函数外,还可以定义其他的成员函数,以及成员变量。

注意:

  1. 不支持静态函数、静态成员变量
  2. 成员函数、变量均为私有

基础代码:

@Component
struct MyComponent {
  // 状态变量
  @State message:string=''
  // 成员变量-数据
  info:string = ''
  // 成员变量-函数
  sayHello=()=>{}
  
  // 成员函数
  sayHi(){
    
  }
  
  build(){
    // .... 描述 UI
  }
}

代码演示:

@Component
struct MyButton {
  @State title:number = 100
  bgColor:string = '#00ff00'
  build() {
    Row() {
      Button(this.title.toString())
        .type(ButtonType.Normal)
        .borderRadius(3)
        .backgroundColor(this.bgColor)
        .onClick(()=>{
          this.title--
        })
      Text()
        .width(10)
        .height(10)
        .backgroundColor(this.bgColor)
        .translate({ x: -5 })
        .rotate({ angle: 45 })
    }
    }
}
@Entry
@Component
struct zy {
  build() {
    Column(){
      MyButton({title:30,bgColor:'#ff00'})
      MyButton()
    }
    .width('100%')
    .height('100%')
  }
}

1.3、 通用样式事件

作用:自定义组件可以通过点语法的形式设置通用样式,通用事件。

基本代码:

子组件()
  .width(100)
  .height(100)
  .backgroundColor(Color.Orange)
  .onClick(() => {
      console.log('外部添加的点击事件')
    })

代码演示:

@Component
struct MyButton {

titel:string = '点击'
  build() {
    Row() {
      Button(this.titel)
        .type(ButtonType.Normal)
        .borderRadius(3)
      Text()
        .width(10)
        .height(10)
        .translate({ x: -5 })
        .rotate({ angle: 45 })
        .backgroundColor('#007dfe')
    }
    }
}
@Entry
@Component
struct zy {
  //仅支持通用事件通用样式
  build() {
    Column({space:10}){
      MyButton({titel:'登录'})
        .onClick(()=>{
        })
      MyButton()
    }
    .width('100%')
    .height('100%')
  }
}

二、构建函数-@BuilderParam 传递 UI

作用:@BuilderParam 该装饰器用于声明任意UI描述的一个元素,类似slot占位符,就是自定义组件允许外部传递 UI。

基础代码:

@Entry
@Component
struct Index {
  build() {
    Column({ space: 15 }) {
      SonCom() {
        // 直接传递进来(尾随闭包)
        Button('传入的结构')
          .onClick(() => {
            AlertDialog.show({ message: '点了 Button' })
          })
      }
    }
  }
}

2.1. 单个@BuilderParam参数

image.png

代码演示:


//单个
@Component
struct mybutton {
  @Builder
  button() {
    Button('按钮')
  }
  @BuilderParam
  a: () => void = this.button

  build() {
    Column() {
      Text('==============')
      this.a()
      Text('==============')
    }
  }
}
@Entry
@Component
struct zy {
  build() {
    Column() {
      mybutton() {
         Button('传递')
      }
    }
    .width('100%')
    .height('100%')
  }
}

2.2. 多个@BuilderParam 参数

子组件有多个BuilderParam,必须通过参数的方式来传入

image.png

代码演示:

@Component
struct aNavBar {
  @Builder
  backbiuder() {
    Text('<==')
  }

  @BuilderParam
  left: () => void = this.backbiuder
  @BuilderParam
  center: () => void = this.backbiuder
  @BuilderParam
  right: () => void = this.backbiuder

  build() {
    Row() {
      this.left()
      this.center()
      this.right()
    }
    .justifyContent(FlexAlign.SpaceBetween)
    .width('100%')
  }
}


@Entry
@Component
struct zy {
  @Builder
  liftbui() {
    Text('返回')
      .fontSize(25)
  }

  @Builder
  centerbui() {
    Text('中间')
      .fontSize(25)
  }

  @Builder
  rightbui() {
    Text('菜单')
      .fontSize(25)
  }

  build() {
    Column() {
      aNavBar({
        left: this.liftbui,
        center: this.centerbui,
        right: this.centerbui
      })
    }
    .width('100%')
    .height('100%')
  }
}

三、状态共享@Prop -父子单向

作用:@Prop 装饰的变量可以和父组件建立单向的同步关系。@Prop 装饰的变量是可变的,但是变化不会同步回其父组件。

3.、1简单类型

简单类型 string、number、boolean、enum

image.png

@Component
struct SonCom {
  @Prop info: string

  build() {
    Button('info:' + this.info)
      .onClick(() => {
        this.info = '子组件修改'
      })
  }
}

@Entry
@Component
struct FatherCom {
  @State info: string = '么么哒'

  build() {
    Column() {
      Text(this.info)
        .onClick(() => {
          this.info = '父组件修改'
        })
      SonCom({
        info: this.info,

      })
    }
    .padding(20)
    .backgroundColor(Color.Orange)
  }
}

image.png

3.2、复杂类型

作用:复杂类型的做法类似,通过回调函数将需要修改的数据传递给父组件即可。

基础代码:

interface User {
  name: string
  age: number
}

@Entry
@Component
struct Index {
  @State
  userInfo: User = {
    name: 'jack',
    age: 18
  }

  build() {
    Column({ space: 20 }) {
      Text('父组件')
        .fontSize(30)
      Text('用户名:' + this.userInfo.name)
        .white()
        .onClick(() => {
          this.userInfo.name = 'rose'
        })
      Text('年龄:' + this.userInfo.age)
        .white()
        .onClick(() => {
          this.userInfo.age++
        })

      Child({
        user: this.userInfo,
       
      })
    }
    .width('100%')
    .height('100%')
    .alignItems(HorizontalAlign.Center)
    .justifyContent(FlexAlign.Center)
    .backgroundColor(Color.Pink)
  }
}

@Component
struct Child {
  @Prop
  user: User

  build() {
    Text('子组件:' + JSON.stringify(this.user))
      .padding(10)
      .backgroundColor('#0094ff')
      .fontColor(Color.White)
      .onClick(() => {

      })
  }
}

@Extend(Text)
function white() {
  .fontSize(20)
  .fontColor(Color.White)
}

image.png