【共创稿事节】收藏、历史、已做:用户行为数据的三层流转设计

一、最高频的写操作,最不能丢的数据

菜谱应用里有一类数据的特点是"小、碎、频":收藏一条菜谱、记下看过的菜、标记本周做过------单条不到 100 字节,但每次交互都可能触发写盘,而且是用户最不能接受丢失的数据(收藏丢了会直接投诉)。1.0.4 起,这类数据由一个 UserDataManager 统一管理,本文复盘它的三层流转设计和四个关键取舍。

二、三层架构:UI 订阅、运行时聚合、磁盘兜底

最底层是 Preferences(user_data 存储),上面是 AppStorage 作为运行时单一事实源,UI 组件全部通过 @StorageLink 订阅。任何页面改收藏,走的是同一条路:操作函数返回新数组 → 写 AppStorage → 同步序列化进 Preferences。没有页面直接碰 Preferences,也没有页面自己维护副本------副本一旦出现,同步 bug 只是时间问题。

启动时的 init 用 getPreferencesSync 一次性把五类记录读进 AppStorage:同步加载保证首帧就有数据,这是"启动可容忍几十毫秒"换来的简单性。

三、取舍一:记录数组 + 单键 JSON,而不是关系库

每类行为数据是一个带时间戳的记录数组(recipeId + createdAt),整体 JSON.stringify 后存进一个 Preferences 键。为什么不上 RDB:数据量小(收藏几十条封顶)、结构稳定、查询就是内存里的 find/filter。关系库的正确引入时机是"需要条件查询和分页"------目前一条都不需要。诚实说这个方案的天花板:JSON 大字符串意味着每次收藏都全量重写整个数组,几百条无感,几千条会有明显的写放大,到那个量级再迁 RDB,接口不用变(persist 是唯一出口)。

四、取舍二:不可变更新是硬约束

toggleFavorite 的写法值得单独说:

ts 复制代码
static toggleFavorite(records: FavoriteRecord[], recipeId: number): FavoriteRecord[] {
  const index = records.findIndex(r => r.recipeId === recipeId)
  if (index >= 0) {
    const newRecords = [...records]
    newRecords.splice(index, 1)
    return newRecords
  }
  return [{ recipeId, createdAt: dateStr }, ...records]
}

取消收藏时先复制再 splice,最后返回的是新数组------不是改完原数组返回它。这是 ArkTS 状态管理 V1 的硬约束:@StorageLink 靠引用变化感知更新,原地 mutate 一个数组,UI 就不动了。所有七个操作函数都遵守这个约定,这一致性比任何单个函数的实现都重要。

五、取舍三:MRU 语义压缩在一个函数里

浏览历史的 addHistory 干了三件事:filter 掉同 id 旧记录、把新记录插到最前、带上时间戳。一次调用完成"去重+置顶+计时",页面侧只需要 records = addHistory(records, id) 一行。历史天然是最近优先(MRU)结构,不需要排序逻辑------插入位置就是排序。清空历史同样只有几行:置空数组 + persist。

六、取舍四:同步 API 的边界

putSync 加 flush 的写路径在这个量级完全够用:单条记录百字节级,全量序列化也就几 KB,磁盘操作毫秒级完成。但同步意味着在 UI 线程做 IO,这个设计成立的前提是数据量小。我已经在 persist 里留了唯一的出口------将来换异步 API 或 RDB,改这一层,七个操作函数和所有页面无感。

七、结语

用户行为数据的设计要点不在存储选型,在流转纪律:单一事实源、不可变更新、写路径收敛到一个函数。做到这三条,数据小的时候跑得轻快,数据大了换存储也不伤筋动骨。

参考资料

  • Preferences 文档(@kit.ArkData)
  • 工程源码:UserDataManager.ets、FavoritePage.ets

#鸿蒙 #HarmonyOS 7(API 26)

相关推荐
●VON3 小时前
芯逻辑:面向 HarmonyOS PC 的图形化编程工作台
华为·harmonyos·鸿蒙·鸿蒙pc
行者-全栈开发19 小时前
【共创稿事节】HarmonyOS 三方库工程化集成:从 ohpm 引入到三方库鸿蒙化的完整闭环
harmonyos·鸿蒙·har·三方库·ohpm·框架适配
贾伟康1 天前
【共创稿事节】一个 UserDataManager 管八类数据:Preferences 持久化的克制用法
java·服务器·前端·harmonyos·arkts·鸿蒙
万物智能信息科技1 天前
六轴传感器Motion驱动框架开发—【万物智能之开源鸿蒙OpenHarmony系统实战开发系列教程】
驱动开发·华为·开源·harmonyos·鸿蒙
熊猫钓鱼>_>1 天前
端侧 NPU 轻量大模型推理接入笔记【鸿蒙心迹】
开发语言·笔记·华为·ai编程·harmonyos·鸿蒙
OH_TPC1 天前
【鸿蒙优选三方库】@ohos/ijkplayer:B 站同源播放器,啥格式都能播
华为·harmonyos·鸿蒙
腾讯端服务1 天前
一码Duo端-Kuikly-iOS折叠屏新UI适配实践
android·ui·ios·kotlin·鸿蒙
OH_TPC1 天前
HarmonyOS APP开发---“云诊室“在线问诊App,需要用到这个库
华为·harmonyos·鸿蒙·1024程序员节
贾伟康2 天前
【共创稿事节】第一张服务卡片:2×2 今日菜谱的克制设计
microsoft·harmonyos·arkts·鸿蒙