鸿蒙ArkUI:声明式UI开发新体验
ArkUI 是 HarmonyOS 的声明式 UI 框架,采用组件化设计,融合了 React、SwiftUI 和 Flutter 的特性。其核心特点包括: 声明式编程:通过描述 UI 状态自动处理渲染,相比传统命令式代码更简洁高效 四大支柱: 装饰器体系(如 @State、@Prop)管理组件状态 丰富的内置组件库(布局/基础/高级组件) 链式属性方法设置样式 响应式状态管理(自动更新 UI) 开
ArkUI 是 HarmonyOS 的声明式 UI 开发框架,与 ArkTS 深度绑定,让你用写代码的方式"画"界面。它融合了 React 的组件化思想、SwiftUI 的声明式语法,以及 Flutter 的响应式状态管理,但针对鸿蒙系统的渲染管线做了深度优化。
以下是 ArkUI 的完整技术图景:
一、核心架构:声明式 vs 命令式
传统 Android/iOS 开发是命令式(Imperative):你一步步告诉系统"创建一个按钮,设置文字,添加到布局,绑定点击事件"。
ArkUI 采用声明式(Declarative):你描述"界面应该长什么样",框架自动处理渲染细节。
// 命令式思维(伪代码)
TextView tv = new TextView();
tv.setText("Hello");
tv.setTextSize(20);
layout.addView(tv);
// ArkUI 声明式思维
Column() {
Text("Hello")
.fontSize(20)
.fontColor('#333')
}
.padding(20)
优势:代码即设计稿,状态自动驱动 UI 刷新,减少冗余代码 50% 以上。
二、四大核心支柱
1. 装饰器体系(Decorators)
装饰器是 ArkUI 的灵魂,标记组件的角色和数据流:
| 装饰器 | 作用 | 类比 |
|---|---|---|
@Entry |
页面入口,每个页面必须有且仅有一个 | main() 函数 |
@Component |
标记自定义组件结构体 | React 的 function Component |
@State |
组件私有状态,变更触发 UI 刷新 | React useState |
@Prop |
父组件单向传递数据给子组件(只读) | Vue props |
@Link |
父子组件双向同步 | Vue v-model |
@Provide/@Consume |
跨层级数据注入(爷孙通信) | React Context |
@Watch |
监听状态变化 | Vue watch |
@Builder |
声明式 UI 构建函数 | 渲染函数 |
2. 内置组件库
ArkUI 提供了丰富的系统组件,按功能分类:
基础组件:Text、Image、Button、TextInput、Slider
容器组件(布局核心):
Column:垂直排列(flex-direction: column)Row:水平排列(flex-direction: row)Stack:层叠布局(z-index stacking)Flex:弹性布局(完整 flexbox 能力)Grid:网格布局List:高性能长列表(自带复用机制)Tabs:标签页容器
高级组件:Web(内嵌网页)、XComponent(OpenGL/C++ 渲染)、Video、Canvas
3. 属性方法链(Modifier)
ArkUI 采用链式调用设置样式,与 SwiftUI 风格一致:
Text("ArkUI")
.fontSize(20) // 文字大小
.fontWeight(FontWeight.Bold)
.fontColor('#ff6600')
.maxLines(2)
.textOverflow({ overflow: TextOverflow.Ellipsis }) // 省略号
.width('100%')
.height(50)
.backgroundColor('#f5f5f5')
.borderRadius(8)
.padding({ left: 12, right: 12 }) // 支持 EdgeInsets 对象
响应式单位:
vp(virtual pixel,虚拟像素,屏幕密度自适应)px(物理像素)%(相对父容器百分比)lpx(大型设备像素,用于平板/2in1 设备)
4. 状态管理(State Management)
ArkUI 的响应式系统基于代理对象(Proxy),当 @State 修饰的变量变更时,框架自动标记脏区域,下一帧刷新。
状态装饰器选择指南:
// 场景1:组件内部状态(如计数器)
@Entry
@Component
struct CounterPage {
@State count: number = 0; // 私有状态
build() {
Button(`${this.count}`)
.onClick(() => this.count++) // 自动触发重绘
}
}
// 场景2:父子单向通信(父→子)
@Component
struct Child {
@Prop title: string; // 父传子,子组件不可修改
build() {
Text(this.title)
}
}
// 场景3:父子双向同步(父子互相影响)
@Component
struct ToggleButton {
@Link isOn: boolean; // 双向绑定
build() {
Button(this.isOn ? 'ON' : 'OFF')
.onClick(() => this.isOn = !this.isOn) // 修改会同步回父组件
}
}
// 使用 @Link 时必须传递引用($变量)
@Entry
@Component
struct Parent {
@State parentSwitch: boolean = false;
build() {
ToggleButton({ isOn: $parentSwitch }) // 注意 $ 符号,表示传递引用
}
}
三、完整实战:待办事项应用
以下是一个包含增删改查、状态管理的完整 ArkUI 示例:
// 数据模型
interface Todo {
id: number;
content: string;
isDone: boolean;
}
@Entry
@Component
struct TodoListPage {
@State todoList: Todo[] = [
{ id: 1, content: '学习 ArkTS', isDone: false },
{ id: 2, content: '掌握 ArkUI', isDone: false }
];
@State inputText: string = '';
// 计算属性(通过 getter 实现)
get unfinishedCount(): number {
return this.todoList.filter(item => !item.isDone).length;
}
// 添加任务
handleAdd() {
if (this.inputText.trim() === '') return;
const newTodo: Todo = {
id: Date.now(),
content: this.inputText,
isDone: false
};
this.todoList.push(newTodo);
this.inputText = ''; // 清空输入框
}
// 删除任务
handleDelete(index: number) {
this.todoList.splice(index, 1);
}
build() {
Column({ space: 16 }) {
// 标题统计
Text(`待办事项 (${this.unfinishedCount} 项未完成)`)
.fontSize(24)
.fontWeight(FontWeight.Bold)
.width('100%')
.padding(20)
// 输入区域
Row({ space: 12 }) {
TextInput({ placeholder: '输入新任务...', text: $$this.inputText })
.width('80%')
.height(48)
.backgroundColor('#f0f0f0')
.borderRadius(8)
Button('添加')
.width('20%')
.height(48)
.type(ButtonType.Capsule)
.onClick(() => this.handleAdd())
}
.padding({ left: 20, right: 20 })
.width('100%')
// 列表区域(使用 List 实现高性能滚动)
List({ space: 12 }) {
ForEach(this.todoList, (item: Todo, index: number) => {
ListItem() {
this.TodoItemBuilder(item, index)
}
.swipeAction({ end: this.DeleteButton(index) }) // 侧滑删除
}, (item: Todo) => item.id.toString()) // 第二个参数是 key,优化 Diff 算法
}
.padding(20)
.layoutWeight(1) // 占据剩余所有空间
.divider({ strokeWidth: 1, color: '#eeeeee' }) // 分割线
}
.width('100%')
.height('100%')
.backgroundColor('#ffffff')
}
// @Builder 构建复用的 UI 结构
@Builder
TodoItemBuilder(item: Todo, index: number) {
Row() {
// 复选框(使用 Toggle)
Toggle({ type: ToggleType.Checkbox, isOn: item.isDone })
.selectedColor('#ff6600')
.onChange((isOn: boolean) => {
item.isDone = isOn; // 修改数组项会自动触发更新
})
Text(item.content)
.fontSize(16)
.fontColor(item.isDone ? '#999999' : '#333333')
.decoration({ type: item.isDone ? TextDecorationType.LineThrough : TextDecorationType.None })
.margin({ left: 12 })
.layoutWeight(1)
}
.width('100%')
.padding(16)
.backgroundColor('#f9f9f9')
.borderRadius(8)
.gesture(
TapGesture()
.onTap(() => {
// 点击切换完成状态
item.isDone = !item.isDone;
})
)
}
// 侧滑删除按钮构建器
@Builder
DeleteButton(index: number) {
Button('删除')
.width(80)
.height('100%')
.type(ButtonType.Normal)
.backgroundColor('#ff4444')
.fontColor('#ffffff')
.onClick(() => this.handleDelete(index))
}
}
四、性能优化技巧
- 使用 List 代替 Column:长列表必须用
List,它会自动复用组件实例(类似 iOS 的 Cell Reuse) - @State 粒度控制:避免大对象直接
@State,拆分为独立的小状态 - Lazy 加载:
LazyForEach配合数据源实现分页加载 - 避免大型 build 函数:将复杂 UI 拆分为多个
@Builder或子组件
五、ArkUI 与主流框架对比
| 特性 | ArkUI | React Native | Flutter | SwiftUI |
|---|---|---|---|---|
| 语言 | ArkTS | JavaScript/Dart | Dart | Swift |
| 渲染 | 自绘引擎(ArkUI-X 跨平台) | Native 组件桥接 | Skia 自绘 | 原生渲染 |
| 性能 | 接近原生(无桥接损耗) | 有通信损耗 | 高性能自绘 | 原生性能 |
| 响应式 | 装饰器驱动 | Hooks/Class | StatefulWidget | Property Wrappers |
| 学习曲线 | 低(TS 开发者友好) | 中 | 中 | 仅限 iOS |
ArkUI 的核心优势在于语言层与渲染层的深度整合:ArkTS 的静态类型信息可以直接用于编译期 UI 布局优化,这是其他框架难以做到的。
需要我详细展开某个特定组件(如动画、手势、自定义绘制)的使用方法吗?
更多推荐

所有评论(0)