鸿蒙实战:19 页面全景汇总与 7 大共享设计模式回顾
鸿蒙实战:19 页面全景汇总与 7 大共享设计模式回顾
前言

图:鸿蒙实战第99篇:19 页面全景汇总与 7 大共享设计模式回顾 运行效果截图(HarmonyOS NEXT)
从第 77 篇开始,我们系统拆解了"鹿鹿"App 全部 19 个页面的完整代码。在第 100 篇(全栈总结)到来之前,本篇从全局视角梳理这些页面背后隐藏的共享设计模式——它们是跨页面复用的"潜规则",掌握这 7 个模式,你就掌握了整个项目的设计语言。
系列导航:98 FormCardsPreview · 100 全栈回顾与未来演进
相关文档:ArkUI 组件参考 · animateTo 显式动画 · AppStorage 状态管理
一、19 页面全景表
1.1 页面分布与代码量
1.2 页面全景汇总表
| # | 页面 | 行数 | 模块 | 核心特性 | 数据源 |
|---|---|---|---|---|---|
| 1 | HomePage | ~350 | 核心 | 5段入场动画 + CTA | ReportDao + AppStorage |
| 2 | CapturePage | ~380 | 核心 | Camera Kit + 三路输入 | Camera Kit + fileIo |
| 3 | WritePage | ~340 | 核心 | onTouch 手写绘图 | Canvas onTouch |
| 4 | AnalyzingPage | 401 | 核心 | 5步进度 + 三表级联 | AppStorage → 3 DAO |
| 5 | ReportDetailPage | ~450 | 核心 | 雷达图 + 情绪卡片 | AppStorage + ReportDao |
| 6 | ArchivePage | 875 | 管理 | 子标签 + 右滑删除 | ArchiveDao + ReportDao |
| 7 | TrendPage | 450 | 管理 | DB+Mock混合折线图 | ReportDao + Mock |
| 8 | MePage | ~280 | 管理 | 统计 + 设置 | HandwritingDao + ReportDao |
| 9 | CoupleHomePage | 857 | 双人 | 三级降级 + 双折线 | RelationDao + ArchiveDao |
| 10 | DuetReportPage | ~500 | 双人 | 双雷达 + 合盘报告 | AppStorage + ReportDao |
| 11 | BindRelationPage | 787 | 双人 | 四步状态机 + 倒计时 | ArchiveDao + RelationDao |
| 12 | LoginPage | 484 | 登录 | Canvas插画 + HMS | UserDao |
| 13 | PhoneLoginPage | 514 | 登录 | 6格Cell验证码 + 倒计时 | UserDao |
| 14 | SharePage | 351 | 分享 | pasteboard + 2×2 Grid | AppStorage |
| 15 | UnclassifiedArchivePage | 527 | 管理 | 长按多选 + 批量归档 | HandwritingDao |
| 16 | FormCardsPreview | 457 | 轻量 | 三种卡片尺寸预览 | Mock |
| 17 | EmptyPage | 399 | 轻量 | Canvas 6层插画 + CTA | — |
| 18 | MetaServiceCard | ~150 | 轻量 | 元服务卡片入口 | AppStorage |
| 19 | TapSharePage | ~120 | 分享 | NFC 碰一碰触发 | AppStorage |
二、7 大共享设计模式
模式 1:四段式页面布局(15/19 页面)
不遵循此布局的 4 个页面:LoginPage(无 TabBar)/ PhoneLoginPage(无 TabBar)/ AnalyzingPage(无 TabBar)/ BindRelationPage(动态标题栏)
复用价值:新增页面只需 build() 中复制四段结构模板,UI 一致性自动保证。
模式 2:递归呼吸动画(3 处复用)
// 通用呼吸动画模式(5 行核心代码)
const pulse = () => {
animateTo({ duration: D, curve: Curve.Smooth, onFinish: () => {
animateTo({ duration: D, curve: Curve.Smooth, onFinish: () => pulse() },
() => { state = MAX })
}}, () => { state = MIN })
}
pulse()
| 页面 | 动画元素 | MIN→MAX | 周期 D |
|---|---|---|---|
| LoginPage | Canvas 整体缩放 | 0.95→1.05 | 3000ms |
| AnalyzingPage | 步骤光圈 opacity | 0.08→0.25 | 700ms |
| CapturePage | 拍照按钮外环 | 1.0→1.15 | 1000ms |
模式 3:多段交错入场(5 个页面)
// 通用交错入场模式
[0, 1, 2, 3, 4].forEach((i) => {
setTimeout(() => {
animateTo({ duration: 400, curve: Curve.FastOutSlowIn }, () => {
opacities[i] = 1
offsets[i] = 0
})
}, baseDelay + i * interval)
})
| 页面 | 段数 | 间隔 | 总时长 |
|---|---|---|---|
| HomePage | 5 | 200ms | ~1200ms |
| ReportDetailPage | 5 | 250ms | ~1300ms |
| ArchivePage | 3+N | 400ms+80ms/卡 | ~900ms |
| SharePage | 3 | 200ms | ~700ms |
| CoupleHomePage | 5 | 150ms | ~900ms |
模式 4:onTouch 按压缩放(11 个页面)
// 通用按压反馈(固定写法)
.onTouch((e: TouchEvent) => {
if (e.type === TouchType.Down) {
animateTo({ duration: 80 }, () => { scale = 0.95 })
} else if (e.type === TouchType.Up || e.type === TouchType.Cancel) {
animateTo({ duration: 150, curve: Curve.EaseOut }, () => { scale = 1.0 })
}
})
.scale({ x: this.xxx_scale, y: this.xxx_scale })
按下 80ms 缩至 95%,抬起 150ms 弹回 100%——接近真实按压的力反馈节奏。
模式 5:AppStorage 跨页数据通道(8 个键)
模式 6:DAO 四步统一模式(5 个 DAO)
// 全项目 DAO 方法唯一写法
static async xxxxxMethod(): Promise<T> {
try {
const store = XxxDao.getStore() // ① 获取 RDB 实例
const rs = await store.query(...) // ② 执行操作
let result: T | null = null
if (rs.goToFirstRow()) { // ③ 读取结果
result = { /* 字段映射 */ }
}
rs.close() // ④ 关闭 ResultSet(必须)
return result
} catch (e) {
hilog.error(TAG, '%{public}s', JSON.stringify(e))
return null
}
}
5 个 DAO 共 833 行代码中,所有 32 个方法均遵循此四步模式,无一例外。
模式 7:调试-生产双模式代码(3 处)
// 模式:生产代码注释保留 + 调试代码激活
private async someNetworkOrAICall(): Promise<Result> {
// ===== 生产代码(解注释后启用)=====
// import { RealService } from '@hmscore/xxx'
// const result = await RealService.call(params)
// return result
// ===== 调试代码(当前运行)=====
await new Promise<void>(resolve => setTimeout(resolve, 800))
return this.generateMockResult()
}
| 文件 | 生产服务 | 注释 API |
|---|---|---|
| LoginPage | HMS Account Kit 一键登录 | AccountAuthService.signIn() |
| PhoneLoginPage | SMS 验证码服务 | cloudSms.sendVerificationCode() |
| AnalyzingPage | MindSpore Lite AI 推理 | AiPipelineService.analyze() |
三、跨页面代码统计
| 模块 | 文件数 | 行数 | 占比 |
|---|---|---|---|
pages/ 页面 |
19 | ~8,500 | 63% |
features/ai/ AI 引擎 |
4 | ~1,200 | 9% |
common/components/ 公共组件 |
6 | ~1,000 | 8% |
features/data/ DAO 层 |
8 | ~900 | 7% |
common/theme/ 主题系统 |
3 | ~600 | 5% |
| 其他 | — | ~800 | 6% |
| 总计 | ~50 | ~13,000 | 100% |
四、常见设计决策对比
4.1 AppStorage 通道 vs 路由传参
| 方案 | 优点 | 缺点 | 本项目选择 |
|---|---|---|---|
| AppStorage | 支持复杂对象、跨多页面 | 需要手动清理 | ✅ 大数据(分析结果) |
| 路由参数 | 干净、生命周期自动 | 仅支持简单类型 | ✅ 简单 ID 传递 |
4.2 Canvas 组件 vs 图片资源
| 方案 | 优点 | 缺点 |
|---|---|---|
| Canvas 动态绘制 | 支持动画、数据驱动、包体积小 | 开发调试成本高 |
| PNG 图片资源 | 开发快 | 不支持动画、包体积大 |
项目选择:雷达图/折线图/插画 → Canvas;图标/Logo → 文字 Emoji + 系统字体
十、注意事项与常见问题
10.1 开发注意事项
在实际开发过程中,需特别注意以下几点:
- API 兼容性:部分接口仅在特定 HarmonyOS NEXT 版本中可用,需做版本条件判断
- 权限模型:采用静态声明(module.json5)+ 动态申请(requestPermissionsFromUser)的两阶段授权
- 生命周期:合理使用
aboutToAppear()和aboutToDisappear()管理资源初始化与释放 - 状态同步:跨页面数据通过 AppStorage 共享,组件内状态使用
@State/@Prop/@Link装饰器
10.2 常见错误与解决方案
常见问题快速排查表:
| 问题类型 | 排查方向 | 参考方法 |
|---|---|---|
| 应用崩溃 | 查看 hilog 错误日志 | hilog.error(TAG, "...", e.message) |
| 状态丢失 | 检查 AppStorage 键名拼写 | 统一使用常量管理键名 |
| 动画不流畅 | 避免在 animateTo 回调中执行 I/O | 动画与数据操作分离 |
十一、最佳实践与性能优化
11.1 代码组织规范
以下规范可显著提升代码可读性与可维护性:
- 分层解耦:UI 逻辑(pages/)与数据操作(DAO/Service)严格分离,不在 build() 中调用数据库
- 组件拆分:单个
@Component保持 100~200 行以内,大型组件拆分为@Builder子函数 - 令牌约束:颜色、字号、间距统一引用
AppColors/AppFonts/AppAnimations,禁止魔数 - 错误处理:异步方法统一返回
Promise<T | null>,异常时hilog.error记录并返回null
11.2 性能优化要点
以下是常见性能优化措施的对比分析:
| 优化维度 | 优化前 | 优化后 | 效果 |
|---|---|---|---|
| 列表渲染 | ForEach 全量渲染 |
LazyForEach 按需渲染 |
内存降低 40-60% |
| 图片加载 | 不指定尺寸 | 指定 width/height |
减少布局重计算 |
| 数据库查询 | 每次重新查询 | 合理缓存 + 精确 Predicates | 查询速度提升 5-10x |
| 动画实现 | 逐帧手动绘制 | animateTo 属性动画 |
稳定 60fps |
| 状态更新 | 全局刷新 | @State 精细化作用域 |
减少无效渲染 |
总结
19 个页面、7 大共享设计模式、约 8,500 行 UI 代码,背后是一套高度一致的"约定优于配置"开发哲学:
- 四段式布局让所有页面视觉一致,新页面不需要思考基础结构
- 递归呼吸动画让 App 有"生命感",3 处复用只需 5 行代码
- AppStorage 跨页通道解耦页面间的数据传递,无需层层透传 props
- DAO 四步模式让所有数据库操作一致,代码审查零认知负担
- 调试/生产双模式让团队可以独立并行开发,合并只需取消注释
下一篇预告:第100篇 全栈回顾——Kit API 全景与未来演进路线图
如果这篇文章对你有帮助,欢迎点赞👍、收藏⭐、关注🔔,你的支持是我持续创作的动力!
相关资源:
- ArkUI 组件参考文档
- animateTo 显式动画
- AppStorage 状态管理
- relationalStore RDB
- 第59篇 入场动画设计
- 第62篇 呼吸脉冲动画
- 第72篇 AppStorage 深度解析
- 第32篇 DAO 设计模式
八、19 页面的完整导航图
鹿鹿 App 19个页面导航关系
├── LoginPage(登录门面)
│ ├── → PhoneLoginPage(手机验证码)
│ └── → HomePage(登录成功)
├── HomePage(首页中枢)
│ ├── → CapturePage(拍照采集)
│ ├── → WritePage(手写板)
│ │ └── → AnalyzingPage(AI分析)
│ │ └── → ReportDetailPage(报告详情)
│ │ └── → SharePage(分享)
│ ├── → ArchivePage(档案管理)
│ │ └── → UnclassifiedArchivePage(未归类)
│ ├── → TrendPage(情绪趋势)
│ ├── → CoupleHomePage(双人空间)
│ │ └── → BindRelationPage(关系绑定)
│ └── → MePage(个人中心)
└── FormCardsPreview + EmptyPage(辅助页)
8.1 7 个通用设计模式速查
| 模式 | 适用场景 | 关键实现 |
|---|---|---|
| 5 段入场动画 | 数据驱动页面 | setTimeout 链式延迟 |
| 呼吸脉冲 | 引导用户操作 | 递归 animateTo |
| 按压缩放 | 所有可点击元素 | onTouch + scale |
| AppStorage 全局状态 | 跨页面数据 | @StorageLink / @StorageProp |
| DAO 数据层 | 数据库操作 | DatabaseService 单例 |
| Empty State | 无数据展示 | EmptyState 组件化 |
| TabBar 底部导航 | 主页面群 | 毛玻璃 + 页签状态 |
九、完整页面架构全景
9.1 页面路由导图
9.2 状态管理分层策略
鸿蒙应用的状态管理遵循三层分离原则:
| 层级 | 装饰器 | 生命周期 | 典型用途 |
|---|---|---|---|
| 全局持久 | @StorageLink / AppStorage |
App 启动至退出 | 用户 ID、登录状态、主题 |
| 页面级 | @State / @Prop / @Link |
页面生命周期 | 列表数据、表单输入 |
| 组件级 | @State (局部) |
组件挂载/卸载 | 动画进度、展开折叠 |
9.3 数据库访问模式
本项目采用 DAO 模式 + 单例 DatabaseService:
DatabaseService (单例)
├── ArchiveDao → archives 表
├── HandwritingDao → handwritings 表
├── ReportDao → reports 表
├── UserDao → users 表
└── RelationDao → relations 表
每个 DAO 封装 CRUD 方法,业务层不直接操作 RdbStore,保持清晰的职责边界。
9.4 设计规范执行情况
| 规范模块 | 执行文件 | 关键类 |
|---|---|---|
| 颜色体系 | AppColors.ets | 36 个设计 Token |
| 字体排版 | AppFonts.ets | 标题/正文/辅助三档 |
| 动画时长 | AppAnimations.ets | 6 个预设时长常量 |
| 阴影层次 | AppShadows.ets | 三级卡片阴影 |
| 导航栏 | HmTitleBar.ets | 统一返回逻辑 |
9.5 延伸学习资源
| 主题 | 推荐篇章 |
|---|---|
| 全流程实战复盘 | 第100篇 全栈回顾与未来演进 |
| 动画体系全貌 | 第58-63篇 动画交互系列 |
| 数据库完整方案 | 第24-33篇 数据持久化系列 |
| Canvas 图表实现 | 第44-51篇 Canvas 绘图系列 |
| 设计规范落地 | 第67-71篇 设计系统系列 |
完成这 19 个页面的学习,你已经拥有一套完整的鸿蒙应用开发认知框架。每一个页面背后都是一个独立但相互关联的技术模块,它们共同构成了「鹿鹿」这款情感分析应用的完整技术生态。
本系列完结篇:第100篇 全栈回顾与未来演进
感谢每一位跟随本系列学习的开发者,愿你的鸿蒙应用早日上架!
本系列技术标签:HarmonyOS NEXT · ArkUI · ArkTS · RDB · Canvas · AI推理 · 动画 · 设计Token
如果这篇文章对你有帮助,欢迎点赞👍、收藏⭐、关注🔔,你的支持是我持续创作的动力!
更多推荐




所有评论(0)