【OpenHarmony/HarmonyOs 】错题本功能从 0 到 1答题记录、去重收录与复习闭环错题本是学习 App 里非常实用的功能。用户不是只需要“做题”更需要知道自己错在哪里、后面怎么复习。本文结合我的「化学视界」项目记录我是如何开发错题本功能的。一、为什么要做错题本化学学习有大量记忆和理解内容比如元素性质、方程式现象、实验操作、有机化学概念等。用户答错题后如果没有复习入口很容易“错过就忘”。所以我在挑战模块里加入了错题本答错时自动收录。答对后可以移除。错题列表可反复练习。设置页能看到错题数量。用户可以清空错题。这让题库不只是一次性练习而是形成“做题 → 出错 → 复习 → 掌握”的闭环。二、错题本的数据应该怎么存我没有保存完整题目内容而是只保存题目 idconst STORAGE_KEYquiz_wrong_question_ids;原因很简单题库本身已经在本地数据中错题本只需要记录“哪些题错过”。这样数据更轻也避免重复保存题干、选项和解析。读取逻辑如下functionreadIds():number[] {try{constraw AppStorage.getstring(STORAGE_KEY);if(!raw || raw.length0) {return[]; }constparsed JSON.parse(raw)asnumber[];if(!Array.isArray(parsed)) {return[]; }returnparsed.filter((n:number) typeofn number); }catch{return[]; } }这里做了容错处理如果本地数据为空、格式异常或解析失败就返回空数组避免页面崩掉。三、答错时自动加入错题集加入错题时要去重否则用户同一道题答错多次错题本会出现重复项exportfunctionaddWrongQuestionId(id:number): void { const ids readIds();if(!ids.includes(id)) { ids.push(id); writeIds(ids); } }这个逻辑虽然简单但很关键。错题本应该反映“哪些题没掌握”而不是“错了多少次”。如果要统计错误次数可以额外做字段但不应该让列表重复。四、答对后移除错题当用户在错题复习里答对某道题后可以从错题集中移除exportfunctionremoveWrongQuestionId(id:number):void{writeIds(readIds().filter((x:number) x ! id)); }我开发时把“移除”设计为明确动作只有复习答对后才移除而不是用户随便进入题目就清掉。这样更符合学习逻辑。五、把错题 id 还原成完整题目错题页面展示时需要根据 id 找回完整题目exportfunctiongetWrongQuestions():QuizQuestion[] {constlist:QuizQuestion[] [];readIds().forEach((id: number) {constq quizData.find((x: QuizQuestion) x.id id);if(q) { list.push(q); } });returnlist; }这里没有直接map而是手动判断q是否存在。这样即使后续题库调整某个旧 id 找不到也不会影响整个错题本。六、挑战页中的错题状态在QuizView中我为错题模式单独维护了一组状态StatewrongQuestions: QuizQuestion[] [];StatewrongIndex: number 0;StatewrongAnswer: string ;StatewrongAnswered: boolean false;StatewrongCorrect: boolean false;StatewrongResultAppear: boolean false;StateexplanationWrongQ: QuizQuestion | null null;为什么不复用练习模式的状态因为错题模式有自己的特殊逻辑答对后可能移除当前题。移除后列表长度会变化。解析区仍然要展示刚答过的题。当前索引需要防止越界。所以我把错题模式独立出来避免和普通练习互相影响。七、防止答对后列表错位项目里有一个很细的状态StateexplanationWrongQ: QuizQuestion |nullnull;它的作用是固定展示刚作答的那道题。因为如果用户答对后这道题会从错题列表移除列表索引可能变化。如果解析区直接依赖wrongQuestions[wrongIndex]就可能显示到下一道题。这是我开发错题本时遇到的一个真实问题数据变化后 UI 绑定对象也跟着变了。解决办法就是把“当前解析题”单独保存一份。八、设置页展示错题数量错题本不只在挑战页出现设置页也会展示入口和数量loadBadge() {this.wrongCount getWrongQuestions().length;constfavs getAllFavorites();this.favoriteCount favs.length;this.unlockCount this.achievementManager.getUnlockedCount(); }设置项中展示徽标{icon:,title:我的错题,subtitle:答错的题目自动收录,action:wrongbook,badge: this.wrongCount 0? String(this.wrongCount) :,badgeColor:#F44336}这样用户不用进入挑战页也能知道自己有没有待复习内容。九、清空错题给用户数据控制权设置页中提供了清空错题的逻辑handleClearConfirm() {if(this.clearActionType wrong) { clearWrongBook();this.wrongCount 0; }else{ clearFavorites();this.favoriteCount 0; }this.showClearConfirm false; }学习数据应该由用户控制。错题本是帮助复习的工具不应该变成无法清理的负担。十、错题本和收藏夹的区别开发时我也思考过一个问题错题本和收藏夹都能保存内容它们有什么区别我的理解是收藏夹是用户主动选择的内容。错题本是系统根据学习结果自动生成的内容。所以收藏夹更像“我觉得重要”错题本更像“我还没掌握”。这两个入口在学习闭环里承担的角色不同不能混在一起。收藏夹适合放常查元素。重点方程式。重要知识点。错题本适合放答错的题目。需要反复练习的知识点。用户短期薄弱内容。正因为这个区别我在代码里也把它们拆成两个工具类收藏由FavoritesManager管理错题由WrongBookStore管理。这样后续维护时不会互相影响。十一、错题本后续可以怎么优化当前错题本已经实现了基础闭环但还可以继续增强给错题增加“错误次数”区分偶然错误和高频错误。给错题增加“最近答错时间”优先复习近期错题。按题目分类统计薄弱模块。在学习统计页展示错题趋势。根据错题自动推荐知识点。不过我没有一开始就把这些都做进去因为基础功能要先稳定。先保证收录、复习、移除、清空这些主流程可靠再做增强会更稳。十二、我开发错题本的总结错题本的开发重点不在 UI而在学习流程❌ 答错自动收录。✅ 答对可以移除。 支持反复复习。 解析区固定当前题。 支持用户清空。从代码上看错题本只保存 id非常轻量从体验上看它把挑战模块从“做完就结束”变成了“持续复习”。这就是学习工具真正有价值的地方。
【OpenHarmony/HarmonyOs 】错题本功能从 0 到 1:答题记录、去重收录与复习闭环
【OpenHarmony/HarmonyOs 】错题本功能从 0 到 1答题记录、去重收录与复习闭环错题本是学习 App 里非常实用的功能。用户不是只需要“做题”更需要知道自己错在哪里、后面怎么复习。本文结合我的「化学视界」项目记录我是如何开发错题本功能的。一、为什么要做错题本化学学习有大量记忆和理解内容比如元素性质、方程式现象、实验操作、有机化学概念等。用户答错题后如果没有复习入口很容易“错过就忘”。所以我在挑战模块里加入了错题本答错时自动收录。答对后可以移除。错题列表可反复练习。设置页能看到错题数量。用户可以清空错题。这让题库不只是一次性练习而是形成“做题 → 出错 → 复习 → 掌握”的闭环。二、错题本的数据应该怎么存我没有保存完整题目内容而是只保存题目 idconst STORAGE_KEYquiz_wrong_question_ids;原因很简单题库本身已经在本地数据中错题本只需要记录“哪些题错过”。这样数据更轻也避免重复保存题干、选项和解析。读取逻辑如下functionreadIds():number[] {try{constraw AppStorage.getstring(STORAGE_KEY);if(!raw || raw.length0) {return[]; }constparsed JSON.parse(raw)asnumber[];if(!Array.isArray(parsed)) {return[]; }returnparsed.filter((n:number) typeofn number); }catch{return[]; } }这里做了容错处理如果本地数据为空、格式异常或解析失败就返回空数组避免页面崩掉。三、答错时自动加入错题集加入错题时要去重否则用户同一道题答错多次错题本会出现重复项exportfunctionaddWrongQuestionId(id:number): void { const ids readIds();if(!ids.includes(id)) { ids.push(id); writeIds(ids); } }这个逻辑虽然简单但很关键。错题本应该反映“哪些题没掌握”而不是“错了多少次”。如果要统计错误次数可以额外做字段但不应该让列表重复。四、答对后移除错题当用户在错题复习里答对某道题后可以从错题集中移除exportfunctionremoveWrongQuestionId(id:number):void{writeIds(readIds().filter((x:number) x ! id)); }我开发时把“移除”设计为明确动作只有复习答对后才移除而不是用户随便进入题目就清掉。这样更符合学习逻辑。五、把错题 id 还原成完整题目错题页面展示时需要根据 id 找回完整题目exportfunctiongetWrongQuestions():QuizQuestion[] {constlist:QuizQuestion[] [];readIds().forEach((id: number) {constq quizData.find((x: QuizQuestion) x.id id);if(q) { list.push(q); } });returnlist; }这里没有直接map而是手动判断q是否存在。这样即使后续题库调整某个旧 id 找不到也不会影响整个错题本。六、挑战页中的错题状态在QuizView中我为错题模式单独维护了一组状态StatewrongQuestions: QuizQuestion[] [];StatewrongIndex: number 0;StatewrongAnswer: string ;StatewrongAnswered: boolean false;StatewrongCorrect: boolean false;StatewrongResultAppear: boolean false;StateexplanationWrongQ: QuizQuestion | null null;为什么不复用练习模式的状态因为错题模式有自己的特殊逻辑答对后可能移除当前题。移除后列表长度会变化。解析区仍然要展示刚答过的题。当前索引需要防止越界。所以我把错题模式独立出来避免和普通练习互相影响。七、防止答对后列表错位项目里有一个很细的状态StateexplanationWrongQ: QuizQuestion |nullnull;它的作用是固定展示刚作答的那道题。因为如果用户答对后这道题会从错题列表移除列表索引可能变化。如果解析区直接依赖wrongQuestions[wrongIndex]就可能显示到下一道题。这是我开发错题本时遇到的一个真实问题数据变化后 UI 绑定对象也跟着变了。解决办法就是把“当前解析题”单独保存一份。八、设置页展示错题数量错题本不只在挑战页出现设置页也会展示入口和数量loadBadge() {this.wrongCount getWrongQuestions().length;constfavs getAllFavorites();this.favoriteCount favs.length;this.unlockCount this.achievementManager.getUnlockedCount(); }设置项中展示徽标{icon:,title:我的错题,subtitle:答错的题目自动收录,action:wrongbook,badge: this.wrongCount 0? String(this.wrongCount) :,badgeColor:#F44336}这样用户不用进入挑战页也能知道自己有没有待复习内容。九、清空错题给用户数据控制权设置页中提供了清空错题的逻辑handleClearConfirm() {if(this.clearActionType wrong) { clearWrongBook();this.wrongCount 0; }else{ clearFavorites();this.favoriteCount 0; }this.showClearConfirm false; }学习数据应该由用户控制。错题本是帮助复习的工具不应该变成无法清理的负担。十、错题本和收藏夹的区别开发时我也思考过一个问题错题本和收藏夹都能保存内容它们有什么区别我的理解是收藏夹是用户主动选择的内容。错题本是系统根据学习结果自动生成的内容。所以收藏夹更像“我觉得重要”错题本更像“我还没掌握”。这两个入口在学习闭环里承担的角色不同不能混在一起。收藏夹适合放常查元素。重点方程式。重要知识点。错题本适合放答错的题目。需要反复练习的知识点。用户短期薄弱内容。正因为这个区别我在代码里也把它们拆成两个工具类收藏由FavoritesManager管理错题由WrongBookStore管理。这样后续维护时不会互相影响。十一、错题本后续可以怎么优化当前错题本已经实现了基础闭环但还可以继续增强给错题增加“错误次数”区分偶然错误和高频错误。给错题增加“最近答错时间”优先复习近期错题。按题目分类统计薄弱模块。在学习统计页展示错题趋势。根据错题自动推荐知识点。不过我没有一开始就把这些都做进去因为基础功能要先稳定。先保证收录、复习、移除、清空这些主流程可靠再做增强会更稳。十二、我开发错题本的总结错题本的开发重点不在 UI而在学习流程❌ 答错自动收录。✅ 答对可以移除。 支持反复复习。 解析区固定当前题。 支持用户清空。从代码上看错题本只保存 id非常轻量从体验上看它把挑战模块从“做完就结束”变成了“持续复习”。这就是学习工具真正有价值的地方。