ArkUI 声明式 UI
ArkUI 是鸿蒙的声明式 UI 框架,心智模型与 SwiftUI/Flutter 同源:UI 由状态驱动,组件由声明构建。示例基于 ArkUI / HarmonyOS NEXT 语境,需在 DevEco Studio 中验证。
页面 = @Entry 组件,组件 = struct + build
一个可运行的页面由两类结构组成:@Entry 装饰的页面组件(路由入口,每页一个),与可复用的 @Component 自定义组件。自定义组件的 UI 全部在 build() 中声明:
typescript
@Component
struct ArticleRow {
title: string = ''
build() {
Row({ space: 8 }) {
Text(this.title).fontSize(16).fontWeight(FontWeight.Medium)
}
.padding(12)
.borderRadius(8)
.backgroundColor('#FFFFFF')
}
}
@Entry
@Component
struct Index {
build() {
List() {
ForEach([1, 2, 3], (item: number) => {
ListItem() { ArticleRow({ title: `文章 ${item}` }) }
}, (item: number) => item.toString())
}
}
}- 组件树由内置组件(
Text/Button/Image/Row/Column/List…)与自定义组件组成; - 通用属性链式配置:尺寸(
.width())、布局(.margin()/.padding())、样式(.backgroundColor())、效果(.borderRadius())等; - 复用 UI 片段用
@Builder函数;重复组件模板用子组件拆分。
布局:容器 + 主轴交叉轴
| 容器 | 用途 |
|---|---|
Row | 水平排列(主轴水平) |
Column | 垂直排列(主轴垂直) |
Flex | 弹性布局,justifyContent/alignItems 控制主轴/交叉轴 |
Stack | 层叠定位 |
List/Grid | 滚动列表 / 宫格,长列表必须用它而不是 Column |
RelativeContainer | 相对定位约束 |
列表性能纪律:ForEach 时给足 key;复用 LazyForEach(数据源需实现 IDataSource);避免在列表项里放重量级组件与实时动画。布局优先用弹性容器撑满,少写死 px。
组件生命周期(页面 / 组件两套)
- 页面级:
onPageShow/onPageHide/onBackPress—— 随路由可见性触发,适合做曝光统计与恢复焦点; - 组件级:
aboutToAppear(组件将创建,做数据准备)、onDidBuild、aboutToDisappear(组件销毁前,清理监听/定时器); - 销毁清理是硬纪律:定时器、事件订阅、长连接必须在
aboutToDisappear释放,否则页面切换后后台泄漏。
路由导航:优先 Navigation
- Navigation(推荐):容器化路由,支持堆栈管理、页面转场动画、标题栏自定义;
NavPathStack+Navigation是现代鸿蒙应用的默认形态; - Router:老一代命令式路由(
router.pushUrl等),存量项目常见,新代码优先 Navigation; - 页面间传参:构造参数(页面组件初始化)、
NavPathStack.pushPath带参;返回结果用回调或集中状态,避免深链路手递手。
样式、动效与主题
- 公共样式沉淀用
@Styles(组件内复用)与@Extend(扩展内置组件);全局主题色走资源文件(resources/base/element/color.json),不把色值散落硬编码; - 动效分层:属性动画
animateTo/animation、转场transition、显式动画keyframeAnimateTo;动效遵守 60fps 预算,大列表内少用位移类动画; - 深浅色:资源里配置
dark与base限定词,UI 颜色引用资源而非写死。
常见坑速查
| 坑 | 现象 | 解法 |
|---|---|---|
| Column 堆长列表 | 卡顿、OOM | 改用 List + LazyForEach |
| ForEach 缺 key | 复用错乱、闪烁 | 提供稳定唯一 key |
| 忘清理定时器 | 页面返回后持续触发 | aboutToDisappear 里清除 |
| 字号写死 px | 大字体模式错位 | 用 fp/lp 或资源字号 |
| 全用 Router 堆逻辑 | 转场/导航不可控 | 迁移到 Navigation + NavPathStack |
| 色值硬编码 | 暗色模式突兀 | 引用 color.json 资源 |
检查清单
- [ ] 页面有且仅有一个
@Entry,公共 UI 已拆为@Component/@Builder; - [ ] 长列表用
List/LazyForEach,key 稳定唯一; - [ ] 监听与定时器在
aboutToDisappear清理; - [ ] 路由统一走
Navigation,传参与返回约定明确; - [ ] 颜色、字号、间距走资源/主题体系,无散落硬编码。