为了账号安全,请及时绑定邮箱和手机立即绑定

鸿蒙自定义组件开发完整指南【1】

标签:
鸿蒙 HarmonyOS

第一篇:自定义组件基础

1.1 什么是自定义组件

自定义组件是鸿蒙ArkTS开发中的核心概念,它就像是搭积木时的一个个预制模块。想象一下,如果我们每次都要从最基础的砖块开始搭建房子,那会非常繁琐。自定义组件就是帮我们预先制作好的"房间模块",可以直接拿来使用,大大提高开发效率。

自定义组件的核心价值:

  • 封装性:将复杂的UI逻辑包装成简单易用的组件
  • 复用性:一次编写,多处使用,避免重复代码
  • 维护性:修改组件时,所有使用该组件的地方都会自动更新
  • 模块化:让代码结构更清晰,便于团队协作

鸿蒙系统中,我们使用@Component装饰器来标识一个自定义组件。每个组件都必须实现build()方法来描述其UI结构,这就像是给组件画一张"设计图纸"。

1.2 创建第一个自定义组件

让我们从一个简单的按钮组件开始,学习如何创建自定义组件。这个按钮组件将支持不同的尺寸,并且可以自定义文本和点击事件。

设计思路:

  1. 定义组件的输入参数(按钮文本、尺寸、点击回调)
  2. 根据不同尺寸返回对应的样式配置
  3. 在build方法中构建UI结构
  4. 处理用户交互事件
@Component
export struct MyButton {
  @Prop buttonText: string = '默认按钮'
  @Prop buttonSize: 'small' | 'medium' | 'large' = 'medium'
  @Prop onButtonClick?: () => void

  private getSizeStyle() {
    switch (this.buttonSize) {
      case 'small':
        return { width: 80, height: 32, fontSize: 12 }
      case 'large':
        return { width: 120, height: 48, fontSize: 18 }
      default:
        return { width: 100, height: 40, fontSize: 14 }
    }
  }

  build() {
    Button(this.buttonText)
      .width(this.getSizeStyle().width)
      .height(this.getSizeStyle().height)
      .fontSize(this.getSizeStyle().fontSize)
      .backgroundColor('#3B82F6')
      .fontColor(Color.White)
      .borderRadius(8)
      .onClick(() => {
        if (this.onButtonClick) {
          this.onButtonClick()
        }
      })
  }
}

1.3 组件属性传递

鸿蒙开发中,组件之间的数据传递是通过特殊的装饰器来实现的。这些装饰器就像是组件之间的"通信协议",规定了数据如何在父子组件之间流动。

主要的属性装饰器类型:

  • @Prop:单向数据流,父组件向子组件传递数据
  • @State:组件内部状态,数据变化时自动刷新UI
  • @Link:双向数据绑定,子组件可以修改父组件的数据
  • @Provide/@Consume:跨级组件通信,适用于深层嵌套场景

让我们通过具体例子来理解这些概念:

@Prop - 父向子传递

@Prop装饰器用于接收父组件传递的数据,这是最常用的数据传递方式。就像函数的参数一样,子组件通过@Prop声明需要接收哪些数据。

下面是一个用户卡片组件的例子,它接收用户名、头像和在线状态等信息:

@Component
struct UserCard {
  @Prop userName: string
  @Prop avatarUrl: string
  @Prop isOnline: boolean = false

  build() {
    Row() {
      Image(this.avatarUrl)
        .width(50)
        .height(50)
        .borderRadius(25)
      
      Column() {
        Text(this.userName)
          .fontSize(16)
          .fontWeight(FontWeight.Bold)
        
        Text(this.isOnline ? '在线' : '离线')
          .fontSize(12)
          .fontColor(this.isOnline ? '#10B981' : '#6B7280')
      }
      .alignItems(HorizontalAlign.Start)
      .margin({ left: 12 })
    }
    .padding(16)
    .backgroundColor('#FFFFFF')
    .borderRadius(12)
  }
}

@State - 组件内部状态

@State装饰器用于管理组件内部的状态数据。当状态发生变化时,鸿蒙框架会自动重新渲染相关的UI部分。这就像是给组件装上了"自动感应器",能够实时响应数据变化。

下面是一个计数器组件,演示了如何使用@State管理内部状态:

@Component
struct Counter {
  @State count: number = 0
  @State isActive: boolean = false

  build() {
    Column() {
      Text(`计数: ${this.count}`)
        .fontSize(24)
        .fontColor(this.isActive ? '#3B82F6' : '#374151')
      
      Row() {
        Button('-')
          .onClick(() => {
            this.count--
            this.isActive = this.count > 0
          })
        
        Button('+')
          .onClick(() => {
            this.count++
            this.isActive = this.count > 0
          })
      }
      .margin({ top: 16 })
    }
    .justifyContent(FlexAlign.Center)
    .width('100%')
    .height(200)
  }
}

1.4 组件使用示例

@Entry
@Component
struct HomePage {
  @State userList: Array<{name: string, avatar: string, online: boolean}> = [
    { name: '张三', avatar: $r('app.media.avatar1'), online: true },
    { name: '李四', avatar: $r('app.media.avatar2'), online: false }
  ]

  build() {
    Column() {
      Text('自定义组件示例')
        .fontSize(20)
        .fontWeight(FontWeight.Bold)
        .margin({ bottom: 20 })

      // 使用自定义按钮
      MyButton({
        buttonText: '小按钮',
        buttonSize: 'small',
        onButtonClick: () => {
          console.log('小按钮被点击')
        }
      })

      // 使用计数器
      Counter()

      // 使用用户卡片
      ForEach(this.userList, (user) => {
        UserCard({
          userName: user.name,
          avatarUrl: user.avatar,
          isOnline: user.online
        })
          .margin({ top: 12 })
      })
    }
    .padding(20)
    .width('100%')
    .height('100%')
  }
}
点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号

举报

0/150
提交
取消