HarmonyOS Next应用开发:UI范式介绍
ArkTS以声明方式组合和扩展组件来描述应用程序的UI,同时还提供了基本的属性、事件和子组件配置方法,帮助开发者实现应用交互逻辑。下面我们以一个具体的示例来说明UI范式的基本语法。如下图所示,当点击按钮时,文本内容从“Hello ,World”变为“你好,鸿蒙”。

基本组成
ArkTS的基本组成如下所示:

此示例我们定义了一个入口组件Index,并且该组件为自定义组件,定义了一个该组件的状态变量message,该状态变量的变化会触发UI的刷新。Index自定义组件组合了系统组件Row、Column、Text、Button,并通过“.”链式调用的形式设置通用样式。Button通过链式调用设置onClick()事件方法,通过触发组件的事件方法改变状态数据,UI从'Hello,World'刷新为'你好,鸿蒙'。
装饰器:
用于装饰类、结构、方法以及变量,并赋予其特殊的含义。
@Entry装饰的自定义组件将作为UI页面的入口。在单个UI页面中,最多可以使用@Entry装饰一个自定义组件。
@Component装饰器仅能装饰struct关键字声明的数据结构。struct被@Component装饰后具备组件化的能力,需要实现build方法描述UI,一个struct只能被一个@Component装饰。
@State表示组件中的状态变量,状态变量变化会触发UI刷新。
UI描述:
以声明式的方式来描述UI的结构,build()函数用于定义自定义组件的声明式UI描述。
@Entry装饰的自定义组件,其build()函数下的根节点唯一且必要,且必须为容器组件,其中ForEach禁止作为根节点。
@Component装饰的自定义组件,其build()函数下的根节点唯一且必要,可以为非容器组件,其中ForEach禁止作为根节点。
@Entry
@Component
struct MyComponent {
build() {
// 根节点唯一且必要,必须为容器组件
Row() {
ChildComponent()
}
}
}
@Component
struct ChildComponent {
build() {
// 根节点唯一且必要,可为非容器组件
Image($r('app.media.icon'))
.width(50)
.height(50)
}
}
build()中不允许声明本地变量;不允许直接使用console.info,但允许在方法或者函数里使用;不允许创建本地的作用域:
build() {
// 不允许声明本地变量
let a: number = 1;
// 不允许console.info
console.info('print debug log');
// 不允许本地作用域
{
}
}
不允许调用没有用@Builder装饰的方法,允许系统组件的参数是TS方法的返回值;不允许使用switch语法,如果需要使用条件判断,请使用if;不允许使用表达式:
@Component
struct ParentComponent {
no:number = 0
doSomeCalculations() {
}
calcTextValue(): string {
return 'Hello World';
}
@Builder doSomeRender() {
Text(`Hello World`)
}
build() {
Column() {
// 反例:不能调用没有用@Builder装饰的方法
this.doSomeCalculations();
// 正例:可以调用
this.doSomeRender();
// 正例:参数可以为调用TS方法的返回值
Text(this.calcTextValue())
// 反例:不允许使用switch语法
switch (this.no) {
case 0:
Text('0')
break;
case 1:
Text('1')
break;
default:
Text('2')
break;
}
// 正例:使用if
if(this.no == 0) {
Text('0')
} else if(this.no == 1) {
Text('1')
} else {
Text('2')
}
// 反例:不允许使用表达式
(this.no > 10) ? Text('100') : Text('0')
}
}
}
不允许直接改变状态变量:
@Component
struct MyComponent {
@State col1: Color = Color.Yellow;
@State col2: Color = Color.Green;
@State count: number = 1;
build() {
Column() {
// 应避免直接在Text组件内改变count的值
Text(`${this.count++}`)
.width(50)
.height(50)
.fontColor(this.col1)
.onClick(() => {
this.col2 = Color.Red;
})
Button("change col1").onClick(() =>{
this.col1 = Color.Pink;
})
}
.backgroundColor(this.col2)
}
}
自定义组件:
可复用的UI单元,可组合其他组件,基于struct实现,struct + 自定义组件名 + {...}且被@Component装饰的组合构成自定义组件,不能有继承关系。对于struct的实例化,可以省略new。自定义组件必须定义build()函数。
系统组件:
框架中默认内置的基础和容器组件,可直接被开发者调用,比如示例中的Column、Text、Button。
属性方法:
组件可以通过链式调用配置多项属性,如fontSize()、width()、height()、backgroundColor()等。
事件方法:
组件可以通过链式调用设置多个事件的响应逻辑,如跟随在Button后面的onClick()。