头图
程序员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. 渲染,并且修改

  2. 使用自定义组件

    a. 无参数使用

    b. 传递参数使用

  3. 测试@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. 调用函数,修改成员变量(普通变量、状态变量)

  2. 使用自定义组件

    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所处的开发者不可见的容器组件上。

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

程序员Feri
1 声望0 粉丝

北京科技大学硕士12年以上软件开发经验阿里云开发者社区专家博主