你好 声明式 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) Divider() Text(this.message) .fontSize(30) } .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) .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() } .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() Divider() SonCom({ str: '你好 子组件' }) } .width('100%') } .height('100%') } }
@Component struct SonCom { @State str: string = '我是 SonCom 组件内的文本'
build() { Column() { Text(this.str) } } }
|

组件导入使用
- 我们不可能把组件都写在一个文件内
- 单独准备文件书写组件,导入使用也是可以的
- 注意 :自定义的组件就不要再用 “@Entry” 装饰器了
新建一个文件( 我这里起名 “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') } } }
|

在其他文件内导入该组件使用
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%') } }
|
