鸿蒙端云一体待办清单实战:ArkTS声明式UI与云端同步落地
一、为什么选择待办清单作为鸿蒙入门案例
第一次上手 HarmonyOS 应用开发,选什么练手项目最合适?我纠结过一阵:太简单的计数器学不到东西,太复杂的商城又容易半途而废。最后我选了待办清单——它看起来简单,却恰好覆盖了鸿蒙开发最核心的几块能力:声明式 UI、状态管理、数据持久化,以及端云协同。更重要的是,华为云鸿蒙开发实践中心里正好有“云同步待办清单:鸿蒙端云一体实战”这个案例,端侧用 ArkTS,云侧用 8 个 FunctionGraph 云函数加 API 网关,跟着做一遍,等于把一条完整的端云链路打通了。这篇文章记录我从零实现这个待办清单的过程,以及联调时踩过的坑。
二、端云一体架构:端侧与云侧如何分工
动手写代码之前,我先把架构想清楚。端侧是 HarmonyOS 应用,负责界面渲染和交互;云侧是华为云 Serverless 组合,负责账号、数据和业务逻辑。两者通过 HTTPS 接口通信,职责边界很清晰:
- 端侧(ArkTS + ArkUI):任务列表、新增与编辑、优先级与截止日期展示、本地缓存与离线可用。
- 云侧(FunctionGraph 云函数):注册登录、任务的增删改查、优先级筛选、截止日期提醒的查询,一共拆成 8 个职责单一的小函数,改一个接口不用动整体。
- 入口(API 网关 APIG):统一收口所有云函数,对外只暴露一套 REST 接口,端侧按路径调用即可。
- 数据层:任务数据按用户隔离存储,每条记录带上用户标识、更新时间戳和同步状态。
这样的分工有一个好处:端侧可以先用本地假数据把界面跑通,再逐个把接口替换成真实请求,联调是渐进式的,不用等云侧全部就绪。
三、开发环境准备
工欲善其事,这一步不要跳过。我的准备清单只有四项:
- DevEco Studio:安装最新稳定版,并下载对应的 HarmonyOS SDK,API 版本要与目标设备一致,否则编译会报找不到符号。
- 模拟器或真机:优先用真机联调,网络请求更接近真实环境;没有真机就用 DevEco 自带的模拟器,记得检查模拟器能否访问外网。
- 华为云账号:开通 FunctionGraph 与 API 网关服务,并创建一个测试用的数据库表或集合来存放任务数据。
- AI DevSpace 云端环境:如果本地电脑配置一般,可以直接在华为云 AI 开发者空间里打开鸿蒙实践中心,云端已经装好工具链和模拟器,浏览器里就能写代码、编译和调试,对新手很友好。
环境准备最容易出问题的是 SDK 版本与工程模板不匹配。我的做法是:新建工程时直接选官方的 Empty Ability 模板,API 版本选模拟器支持的版本,第一次编译通过之后再往里面加业务代码。
四、端侧实现:声明式 UI 与状态管理
ArkTS 的声明式 UI 写起来很直观,界面就是状态的函数。待办清单的核心是一个任务列表,我用 @State 装饰器持有任务数组,数组变化时界面自动刷新。关键代码如下:
@Entry
@Component
struct TodoPage {
@State todos: TodoItem[] = [];
@State inputText: string = '';
build() {
Column() {
TextInput({ placeholder: '输入新任务' })
.onChange((value: string) => {
this.inputText = value;
})
Button('添加任务').onClick(() => {
this.addTodo();
})
List() {
ForEach(this.todos, (item: TodoItem) => {
ListItem() {
Row() {
Checkbox().select(item.done)
.onChange((checked: boolean) => {
item.done = checked;
this.syncTodo(item);
})
Text(item.title)
.decoration({ type: item.done ? TextDecorationType.LineThrough : TextDecorationType.None })
Text(item.priority)
Text(item.dueDate)
}
}
})
}
}
}
}
这里有几个细节值得注意:第一,数组元素的字段变化要能触发刷新,最好把任务定义成类并用 @Observed 配合 @ObjectLink,否则勾选框的状态可能不同步;第二,优先级用枚举表示(高、中、低),并用不同颜色区分,扫一眼就能抓住重点任务;第三,截止日期用日期选择器输入,保存时统一转成时间戳,避免字符串格式带来的解析问题。
五、云侧实现:云函数与接口契约
云侧我按“一个函数只做一件事”来拆:注册、登录、创建任务、查询任务列表、更新任务、删除任务、按优先级筛选、查询即将到期任务。端侧调用的接口契约保持简单,统一用 JSON:
- POST /todos:创建任务,请求体带标题、优先级和截止日期。
- GET /todos:按用户拉取任务列表,支持按完成状态过滤。
- PUT /todos/{id}:更新任务状态或内容。
- DELETE /todos/{id}:删除任务。
- POST /login:登录换取会话凭证,后续请求在请求头里携带。
云函数的骨架以 Node.js 为例,入口只做三件事:解析参数、校验身份、操作数据库并返回统一的结果结构。实际开发中我先在本地用少量假数据把函数逻辑跑通,再部署到 FunctionGraph 上通过 API 网关联调,这样出问题时能快速定位是函数的问题还是网关配置的问题。
六、端云同步:离线可用与冲突处理
待办清单最怕的是没网就不能用。我的做法是端侧本地先用 Preferences 存一份任务快照,界面优先读本地数据,网络恢复后再与云端做增量同步。同步策略定得很简单:每条任务带一个 updatedAt 时间戳,两边比较后以更新的一方为准;如果同一条任务两边都改过,就以后写入的时间为准,并在界面上用一个小标记提示用户自行确认。
登录态的处理也值得单独说一句:登录成功后把凭证存在本地的安全存储里,接口请求失败返回 401 时自动引导重新登录,不要让用户在不知情的情况下继续操作,否则会产生一堆同步失败的脏数据。
七、联调踩坑记录
整个实践下来,真正花时间的不是写界面,而是联调。下面五条是我实际踩过的坑,分享出来帮大家绕路:
- 模拟器访问云端域名:模拟器默认网络配置可能拦截自定义域名,先确认应用申请了网络权限,再检查域名解析是否正常。
- API 网关签名与时间戳:开启签名校验时,端侧时间戳与服务器时间差不能太大,模拟器时间不同步会直接导致签名失败。
- 云函数冷启动:第一次调用会慢几百毫秒,加载态一定要做好,否则用户会以为按钮没反应而重复提交。
- 时区与截止日期:截止日期务必存时间戳,展示时再按设备时区换算,直接存日期字符串会在跨时区时错一天。
- 跨域与白名单:通过浏览器做调试时,接口域名要加进允许列表,否则请求会在预检阶段就被拦住。
八、打包、测试与发布准备
功能跑通后,我按这个顺序收尾:先跑真机,逐项核对新增、勾选、删除、同步这四条主流程;再用 hvigorw assembleHap 打正式包,确认签名配置正确;最后把云侧的测试数据清掉,并把接口的访问频率限制打开,避免测试阶段的脏数据和误调用带到线上。发布前还建议把隐私说明补齐,待办清单涉及用户账号和个人数据,合规环节不要省。
九、总结与下一步
做完这个待办清单,我最大的感受是:鸿蒙的端云一体开发并没有想象中复杂,难的是把职责边界想清楚。端侧管好界面与状态,云侧管好数据与接口,中间用一份清晰的接口契约连起来,联调就能一步步推进。下一步我打算在这个基础上继续加两个能力:一是分布式数据管理,让手机和平板上的任务自动同步;二是把任务提醒做成系统级通知,并在超级终端的流转场景下验证多设备接续使用的体验。这两个方向正好对应 HarmonyOS 最核心的分布式能力,做完之后再来写一篇复盘。
- 点赞
- 收藏
- 关注作者
评论(0)