open harmony 项目实战用 ArkTS 实现诗词收藏和阅读历史收藏和阅读历史是学习类 App 中非常常见的功能。用户看到喜欢的诗词希望可以收藏读过的内容也希望能在“我的”页面看到记录。在“语文视界”项目中我把这部分逻辑放在PoetryViewModel.ets中页面只负责展示和触发操作。这样做的好处是业务逻辑更集中后续维护也更轻松。❤️一、为什么用 ViewModel 管收藏和历史如果把收藏逻辑写在诗词列表、诗词详情、首页推荐等多个页面里会出现很多重复代码收藏 id 怎么保存取消收藏怎么处理列表里的收藏状态怎么同步阅读历史怎么去重历史记录最多保存多少条所以项目选择让PoetryViewModel管这些业务。二、核心字段exportclassPoetryViewModel{privatefavoriteIds:number[] [];privatereadHistoryIds:number[] [];privatepoetryCache:Mapnumber,Poetry newMapnumber,Poetry(); }这里没有保存完整诗词对象而是保存 id 列表。真正展示时再通过缓存找到对应诗词。这种方式更轻也更容易处理数据更新。三、构建诗词缓存项目启动时会构建一个Map缓存privatebuildCache():void{for(constpoetry of POETRY_DATA) {this.poetryCache.set(poetry.id, poetry); } }后续通过 id 查询诗词时就不用每次遍历完整数组了。四、收藏数据如何保存收藏列表通过AppStorage保存为 JSON 字符串privateloadFavorites():void{conststored AppStorage.getstring(poetry_favorites);if(stored) {try{this.favoriteIds JSON.parse(stored); }catch{this.favoriteIds []; } } }privatesaveFavorites():void{ AppStorage.setOrCreate(poetry_favorites, JSON.stringify(this.favoriteIds)); }这里加了try/catch防止存储内容异常导致页面崩溃。五、切换收藏状态收藏和取消收藏使用同一个方法publictoggleFavorite(id: number): boolean {constindex this.favoriteIds.indexOf(id);if(index -1) {this.favoriteIds.splice(index,1);this.saveFavorites();returnfalse; }else{this.favoriteIds.push(id);this.saveFavorites();returntrue; } }返回值表示切换后的收藏状态。页面拿到返回值后就可以马上更新 UI。六、详情页如何使用诗词详情页只需要调用privatetoggleFavorite(): void {this.isFavorite poetryViewModel.toggleFavorite(this.poetryId); }页面不需要知道收藏数据到底存在什么地方也不需要关心 JSON 序列化。七、首页推荐里的收藏同步首页推荐和热门诗词列表也能切换收藏。切换后需要同步更新当前列表中的对象privatetoggleFavorite(poetryId:number):void{constresult poetryViewModel.toggleFavorite(poetryId);constinRec this.recommendedPoetry.find(pp.id poetryId);if(inRec) { inRec.isFavorite result; }this.favoriteCount poetryViewModel.getFavoriteCount(); }这样用户点了爱心后当前页面能立即反馈。八、阅读历史如何维护阅读历史的逻辑比收藏多一步同一首诗重复阅读时要移到最前面而不是重复插入。publicaddToReadHistory(id: number): void {constindex this.readHistoryIds.indexOf(id);if(index -1) {this.readHistoryIds.splice(index,1); }this.readHistoryIds.unshift(id);if(this.readHistoryIds.length 50) {this.readHistoryIds this.readHistoryIds.slice(0,50); }this.saveReadHistory(); }这里还限制最多保存 50 条避免历史列表无限增长。九、我的页面如何展示数据MyPage会读取收藏数、阅读历史数和学习天数privateloadStats(): void {this.favoriteCount poetryViewModel.getFavoriteCount();this.readHistoryCount poetryViewModel.getReadHistoryCount();conststreak AppStorage.getnumber(learn_streak);this.currentStreak streak ! undefined ? streak :0; }这就形成了一个简单的数据看板让用户能看到自己的学习积累。十、可以继续优化的地方后续可以考虑收藏列表支持排序。阅读历史支持清空。收藏数据迁移到持久化数据库。收藏和历史支持备份恢复。添加“最近阅读”快捷入口。总结收藏和阅读历史看似简单但真正写起来要考虑数据保存、状态同步、重复阅读、异常兜底和页面展示。在这个项目中我用PoetryViewModel AppStorage id 列表实现了一个轻量但完整的方案很适合本地学习类 OpenHarmony App 使用。