一文轻松拿下HarmonyOS NEXT的自定义组件

举报
程序员Feri 发表于 2025/03/06 14:34:02 2025/03/06
【摘要】 程序员Feri一名12年+的程序员,做过开发带过团队创过业,擅长Java、嵌入式、鸿蒙、人工智能等,专注于程序员成长那点儿事,希望在成长的路上有你相伴!君志所向,一往无前! 1.自定义组件基础在ArkUI中,UI显示的内容均为组件,由框架直接提供的称为系统组件,由开发者定义的称为自定义组件。相比于之前学习的轻量级 UI 复用机制 @Builder,自定义组件的功能更为强大,日常开发中如果要进...

程序员Feri一名12年+的程序员,做过开发带过团队创过业,擅长Java、嵌入式、鸿蒙、人工智能等,专注于程序员成长那点儿事,希望在成长的路上有你相伴!君志所向,一往无前!


1.自定义组件基础

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

相比于之前学习的轻量级 UI 复用机制 @Builder,自定义组件的功能更为强大,日常开发中如果要进行 UI 或业务逻辑进行复用,需要掌握自定义组件的能力。

2.自定义组件语法格式

@Entry
@Component
struct Index {
  build() {
    Column() {
      // 自定义组件
      HelloComponent()
    }
  }
}

3.基本使用

如何创建自定义组件呢?

说明

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

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

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

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

  }
}
  • struct:自定义组件基于struct实现,struct + 自定义组件名 + {…}的组合构成自定义组件,不能有继承关系。对于struct的实例化,可以省略new。

  • @Component:@Component装饰器仅能装饰struct关键字声明的数据结构。

  • build()函数:build()函数用于定义自定义组件的声明式UI描述,自定义组件必须定义build()函数。

  • @Entry:@Entry装饰的自定义组件将作为UI页面的入口。在单个UI页面中,最多可以使用@Entry装饰一个自定义组件。

  • @Preview:如果想要单独预览组件,可以使用@Preview 进行装饰

4.练一练

  1. 创建自定义组件(写到一个文件,拆分到其他文件)

a. build()中添加UI 描述

b. 定义状态变量

c. 渲染,并且修改

  1. 使用自定义组件

a. 无参数使用

b. 传递参数使用

  1. 测试@Preview预览组件

下面为参考的示例代码:

// 定义组件
@Component
struct HelloComponent {
  // 自己的状态
  @State message: string = 'Hello, World!';

  build() {
    // HelloComponent自定义组件组合系统组件Row和Text
    Row() {
      Text(this.message)
        .onClick(() => {
          // 状态变量message的改变驱动UI刷新,UI从'Hello, World!'刷新为'Hello, ArkUI!'
          this.message = 'Hello, ArkUI!';
        })
    }
  }
}

// 使用组件
@Entry
@Component
struct Index {
  build() {
    Column() {
      HelloComponent()
      // 只要愿意,可以 使用任意多次
      HelloComponent()
      // 还可以 传递参数给子组件,覆盖子组件成员变量的值
      HelloComponent({message:'hello Feri'})
    }
  }
}

// HelloComponent.ets

// 定义组件
@Component
export struct HelloComponent {
  // 自己的状态
  @State message: string = 'Hello, World!';

  build() {
    // HelloComponent自定义组件组合系统组件Row和Text
    Row() {
      Text(this.message)
        .onClick(() => {
          // 状态变量message的改变驱动UI刷新,UI从'Hello, World!'刷新为'Hello, ArkUI!'
          this.message = 'Hello, ArkUI!';
        })
    }
  }
}

页面.ets-------------------

import {HelloComponent} from 'HelloComponent'

// 使用组件
@Entry
@Component
struct Index {
  build() {
    Column() {
      HelloComponent()
      // 只要愿意,可以 使用任意多次
      HelloComponent()
      // 还可以 传递参数给子组件,覆盖子组件成员变量的值
      HelloComponent({message:'hello itheima'})
    }
  }
}

5.成员函数/变量

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

注意:

  1. 不支持静态函数、静态成员变量
  2. 成员函数、变量均为私有
@Component
struct MyComponent {
  // 状态变量
  @State message:string=''
  // 成员变量-数据
  info:string = ''
  // 成员变量-函数
  sayHello=()=>{}
  
  // 成员函数
  sayHi(){
    
  }
  
  build(){
    // .... 描述 UI
  }
}

亲自动手实现以下自定义组件

  1. 添加自定义组件

a. 定义成员变量(普通变量、状态变量)

b. 定义成员函数

c. 调用函数,修改成员变量(普通变量、状态变量)

  1. 使用自定义组件

a. 无参数调用

b. 传递参数调用

参考代码
// HelloComponent.ets

@Component
export struct HelloComponent {
  // 成员变量
  info: string = '感觉自己闷闷哒'
  // 成员变量也可以是函数
  sayHello=()=>{}
  // 状态变量
  @State message: string = 'Hello, World!';

  // 成员函数
  sayHi() {
    console.log('你好呀')
  }

  build() {
    // HelloComponent自定义组件组合系统组件Row和Text
    Column() {
      Text(this.message)
      Text(this.info)
      Button('修改数据')
        .onClick(() => {
          this.info = '(*  ̄3)(ε ̄ *)'
          this.message = 'Hello,ArkTS'
          this.sayHi()
          this.sayHello()
        })

    }
  }
}

// 页面的.ets

import { HelloComponent } from './components/HelloComponent'

@Entry
@Component
struct Index {
  build() {
    Column() {
      // 使用组件内部定义的初始值
      HelloComponent()
      // 使用传入的值,覆盖子组件的默认值
      HelloComponent({ info: '你好', message: 'ArkTS' })
      // 函数也可以传入
      HelloComponent({ sayHello(){ console.log('传入的逻辑') } })
    }
  }
}

7.通用样式事件

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

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

练一练:

  1. 添加自定义组件,随意设置内容
  2. 使用自定义组件,通过点语法设置通用样式
@Component
struct MyComponent2 {
  build() {
    Button(`Hello World`)
  }
}

@Entry
@Component
struct Index {
  build() {
    Row() {
      MyComponent2()
        .width(200)
        .height(300)
        .backgroundColor(Color.Red)
        .onClick(() => {
            console.log('外部添加的点击事件')
          })
    }
  }
}

说明
ArkUI给自定义组件设置样式时,相当于给MyComponent2套了一个不可见的容器组件,而这些样式是设置在容器组件上的,而非直接设置给MyComponent2的Button组件。

通过渲染结果我们可以很清楚的看到,背景颜色红色并没有直接生效在Button上,而是生效在Button所处的开发者不可见的容器组件上。

好啦,就说到这里啦,希望每天坚持!

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。