你好 声明式 UI

乾坤初翻转鸿蒙才开始
你们老说的 “声明式 UI” 到底是个啥 ?
我到底应该怎么写代码 ?
咋设置宽高 ? 点击事件咋办 ?

  • ArkTS 以声明方式组合和扩展组件来描述应用程序的 UI
  • 同时还提供了基本的属性、事件和子组件配置方法,帮助开发者实现应用交互逻辑。
  • 当前章节的所有内容都是以了解声明式 UI 为主,细节内容后面会详细介绍

一、创建组件

  • 根据组件构造方法的不同,创建组件包含 有参数 和 无参数 两种方式。
  • 注意 : 创建组件时不需要 new 运算符

无参数组件

  • 如果 组件定义没有包含必选构造参数,则组件后面的 “()” 内不需要配置任何内容

例如 :
Divider 分割线组件就不包含任何构造参数
我们在时候用的时候直接书写 “Divider()” 即可

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
@Entry
@Component
struct Index {
@State message: string = 'Hello Harmony'

build() {
Row() {
Column() {
Text(this.message)
.fontSize(50)
.fontWeight(FontWeight.Bold)
Divider() // 分割线组件,无需传递参数
Text(this.message)
.fontSize(50)
.fontWeight(FontWeight.Bold)

}
.width('100%')
}
.height('100%')
}
}

有参数组件

  • 如果组件定义包含必选构造参数,则组件后面的 “()” 内需要配置相应参数

例如 :
Image 图片展示组件的 必选 参数 src
我们在使用的时候就要书写 “Image(‘图片地址’)”
不同的组件会有不同的参数规则和方式,需要根据组件的规则来配置相应的参数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
@Entry
@Component
struct Index {
@State message: string = 'Hello Harmony'

build() {
Row() {
Column() {
Text(this.message)
.fontSize(50)
.fontWeight(FontWeight.Bold)
Image('https://img2.baidu.com/it/u=4091031159,3987317755&fm=253&fmt=auto&app=138&f=JPEG?w=888&h=500')

}
.width('100%')
}
.height('100%')
}
}

例如 :
Text 文本展示组件的 非必选 参数 content
也就是可以传递参数,也可以不传递参数
我们在使用的时候根据需求来决定
可以是 “Text(‘Hello Harmony’)” 或者 “Text()”

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
@Entry
@Component
struct Index {
@State message: string = 'Hello Harmony'

build() {
Row() {
Column() {
Text(this.message) // 传递参数
.fontSize(50)
.fontWeight(FontWeight.Bold)
Divider()
Text() // 不传递参数
}
.width('100%')
}
.height('100%')
}
}

变量或者表达式也是可以用于参数赋值的
如果是表达式的话,其表达式结果必须满足参数类型要求

1
2
3
Image(this.imagePath)
Image('https://' + this.imageUrl)
Text(`count: ${this.count}`)
  • 以上只是一些基本介绍,我们暂时了解一下
  • 后面我会这些内容进行详细讲解,目前只是先认识

二、配置属性

  • 组件是可以通过配置属性来描述当前组件的一些 UI 样式的( 其实就是我们以前的 CSS 做的工作 )
  • 属性方法以 “.” 链式调用的方式配置 系统组件 的样式和其他相关属性
  • 建议每一个属性单独书写一行,方便阅读

    例如 :
    fontSIze() 方法可以配置 Text() 组件的 文字大小

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
@Entry
@Component
struct Index {
@State message: string = 'Hello Harmony'

build() {
Row() {
Column() {
Text(this.message)
.fontSize(50) // 修饰文本文字大小为 50vp
Divider()
Text(this.message)
.fontSize(30) // 修饰文本文字大小为 30vp
}
.width('100%')
}
.height('100%')
}
}

一个组件可以配置多个属性来修饰
配置多个属性的时候采用链式调用的方式即可

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
@Entry
@Component
struct Index {
@State message: string = 'Hello Harmony'

build() {
Row() {
Column() {
Text(this.message)
.fontSize(50) // 修饰了文字大小为 50vp
.fontColor('red') // 同时修饰了文本眼色为 红色
}
.width('100%')
}
.height('100%')
}
}

  • 这里只是展示了几个属性,用于了解声明式 UI
  • 后面我们会详细讲解配置属性
  • ArkUI 也给系统组件内置了一些枚举类型供我们使用,后面我们会一一说到

三、配置事件

  • 组件是可以通过配置事件来给组件添加一些事件行为的
  • 和配置属性一样,配置事件也是一 “.” 的方式链式调用
  • 建议每一个事件单独书写一行,方便阅读

    例如 :
    onClick() 方法可以给组件添加点击事件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
@Entry
@Component
struct Index {
@State count: number = 0

build() {
Row() {
Column() {
Text(`${ this.count }`)
.fontSize(50)
Divider()
Button('Click Me')
.onClick(() => this.count++)
}
.width('100%')
}
.height('100%')
}
}
  • 这里也只是简单介绍,后面我们会详细说配置事件的规则

四、自定义组件

  • 除了系统内置的常用组件以外,我们也可以自己定义一些组件

    官方 : 在 ArkUI 中,UI 显示的内容均为组件,由框架直接提供的称为系统组件,由开发者定义的称为自定义组件。在进行 UI 界面开发时,通常不是简单的将系统组件进行组合使用,而是需要考虑代码可复用性、业务逻辑与 UI 分离,后续版本演进等因素。因此,将 UI 和部分业务逻辑封装成自定义组件是不可或缺的能力。

  • 自定义组件的特点
    • 可组合:允许开发者组合使用系统组件、及其属性和方法。
    • 可重用:自定义组件可以被其他组件重用,并作为不同的实例在不同的父组件或容器中使用。
    • 数据驱动 UI 更新:通过状态变量的改变,来驱动 UI 的刷新。

定义一个组件

  • 使用 “@Component” 装饰器来修饰 struct 成为一个组件
1
2
3
4
5
6
@Component
struct SonCom {
build() {
/* ... */
}
}

此时,我们就定义了一个叫做 SonCom 的组件
该组件是可以直接在其他组件内使用的
只不过暂时这个组件内是没有内容的
接下来我们就来扩充一下

1
2
3
4
5
6
7
8
9
10
@Component
struct SonCom {
@State str: string = '我是 SonCom 组件内的文本'

build() {
Column() {
Text(this.str)
}
}
}

这个组件准备好以后, 我们就可以直接使用了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
@Entry
@Component
struct Index {
@State message: string = 'Hello Harmony'

build() {
Row() {
Column() {
Text(this.message)
.fontSize(50)
Divider()
SonCom() // 使用自定义组件 SonCom
}
.width('100%')
}
.height('100%')
}
}

@Component
struct SonCom {
@State str: string = '我是 SonCom 组件内的文本'

build() {
Column() {
Text(this.str)
}
}
}

组件使用传参

  • 自己定义的组件是可以直接复用的
  • 并且在使用自定义组件的时候,可以直接给子组件内某个变量赋值
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
@Entry
@Component
struct Index {
@State message: string = 'Hello Harmony'

build() {
Row() {
Column() {
Text(this.message)
.fontSize(50)
Divider()
SonCom() // 不传递参数,子组件内部的 str 就是本身设置的值
Divider()
SonCom({ str: '你好 子组件' }) // 传递参数,子组件内部的 str 就是传递的值
}
.width('100%')
}
.height('100%')
}
}

@Component
struct SonCom {
@State str: string = '我是 SonCom 组件内的文本'

build() {
Column() {
Text(this.str)
}
}
}

组件导入使用

  • 我们不可能把组件都写在一个文件内
  • 单独准备文件书写组件,导入使用也是可以的
  • 注意 :自定义的组件就不要再用 “@Entry” 装饰器了
  1. 新建一个文件( 我这里起名 “SonCom.ets” ),定义组件

    注意书写 export 关键字,将该文件内的 struct 导出

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    @Component
    export struct SonCom {
    @State str: string = '我是 SonCom 内的文本内容'

    build() {
    Column() {
    Text(this.str)
    .fontSize(22)
    .fontColor('red')
    }
    }
    }

  2. 在其他文件内导入该组件使用

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    import { SonCom } from './SonCom'

    @Entry
    @Component
    struct Index {
    @State message: string = 'Hello Harmony'

    build() {
    Row() {
    Column() {
    Text(this.message)
    .fontSize(50)
    Divider()
    SonCom()
    }
    .width('100%')
    }
    .height('100%')
    }
    }