第 32 课任务卡片按状态分组与本地持久化这一课我们继续沿着“任务管理页个人工作台偏好”主线往下推进。上一课我们已经让任务列表支持表格视图卡片视图这一课继续把卡片视图做得更像真实后台系统让当前页卡片支持“平铺显示 / 按状态分组”两种组织方式并把这份偏好持久化到 localStorage。这节课一句话在做什么这一课我们完成了 6 件事给任务卡片列表新增了平铺显示 / 按状态分组两种分组模式。把当前分组模式保存到了localStorage。刷新任务页后卡片分组模式会自动恢复。让卡片分组只作用于当前页任务不改筛选结果和分页语义。保持卡片里的勾选、编辑、删除、字段显隐继续可用。补上了单元测试、E2E 测试和课程文档。这一课最重要的设计结论这一课最重要的结论是卡片分组方式属于展示偏好不属于业务筛选条件。为什么“按状态分组”不是筛选很多初学者第一次做这个功能时很容易把它误写成再加一个筛选条件或者干脆改变任务结果集但这其实是不对的。1. 分组不会改变命中的任务集合无论当前卡片列表是平铺显示按状态分组命中的任务集合都没有变。它不会改变keywordstatusFilterpriorityFiltersortOptioncurrentPage它改变的是当前页任务怎么分块展示同一批卡片怎么更容易阅读所以它本质上仍然是展示偏好而不是业务状态2. 分组偏好更适合进localStorage为什么这次也没有把“分组模式”写进 URL因为 URL 更适合表达这次访问到底想看哪一批数据而卡片分组模式更像我个人更习惯怎么读这批卡片这种偏好应该满足的是刷新后保留下次进入页面自动恢复不污染分享链接所以这一课继续把它放进了localStorage3. 分组应该作用于“当前页切片结果”这是这节课最值得你真正想清楚的点。当前任务页已经有一套稳定的数据流原始任务筛选排序分页切片渲染当前页这一课我们没有把分组插到分页前面而是放在当前页切片之后也就是先得到paginatedTasks再把paginatedTasks按状态分区这样做的好处是不会破坏现有分页语义不会让页码和实际看到的数据范围打架更符合“这是当前页展示方式”的定位这在真实后台里非常重要。这一课在useTasksPage里做了什么文件src/composables/useTasksPage.ts这次新增的核心状态仍然放在任务页组合式函数里因为分组模式是页面级偏好不是某个卡片组件自己的临时状态1. 新增了分组模式类型、默认值和本地存储 key这次新增了TaskListGroupingModeTaskListGroupingModeOptionItemTaskListGroupSectionDEFAULT_TASK_LIST_GROUPING_MODETASK_LIST_GROUPING_MODE_STORAGE_KEY这套设计继续沿用前几课已经反复训练过的工程模式先定义稳定类型再定义默认值再定义本地存储 key最后把读取、标准化、写回流程补齐2. 新增了“读取 - 校验 - 标准化 - 写回”的分组偏好流程这次新增了这几类函数isTaskListGroupingModenormalizeTaskListGroupingModereadPersistedTaskListGroupingModepersistTaskListGroupingMode它们的职责很清楚从本地存储读出旧值判断这个旧值是不是合法非法就回退到none再通过watch(..., { immediate: true })把标准化结果写回去这套流程不是“麻烦”而是工程必要动作。因为真实项目里本地存储经常会遇到历史旧值手动篡改老版本遗留数据所以不能直接相信它。3. 新增了页面级分组状态和行为这次新增的页面级状态主要有taskListGroupingModetaskListGroupingModeOptionspaginatedTaskGroupshandleTaskListGroupingModeChange()最值得你注意的是paginatedTaskGroups不是基于全部筛选结果生成的而是基于 paginatedTasks 生成的。这说明我们一直在坚持分页决定“当前页有哪些任务”分组决定“当前页这些任务怎么组织展示”这两个层次不能混。4. 新增了分组结果生成函数这次新增了createTaskListGroupSections(taskList)它做的事情很简单但很典型按稳定状态顺序遍历把属于同一状态的任务收集起来只保留非空分组输出统一结构给卡片组件渲染这里有两个很重要的工程细节分组顺序固定为状态顺序而不是随机顺序分组内任务顺序继续保留当前页原有排序结果这样页面行为才稳定、可预测、可测试。这一课在界面层做了什么文件src/components/tasks/TaskListGroupingSettings.vuesrc/components/tasks/TaskCardList.vuesrc/views/TasksView.vue1. 新增了TaskListGroupingSettings这个组件负责展示“平铺显示 / 按状态分组”切换入口展示当前分组模式摘要通过emit把切换动作抛给父层它没有自己处理localStorage分组计算页面状态它仍然只做UI用户输入这说明你现在已经在逐步建立一个很重要的前端边界意识输入组件负责交互页面级 composable 负责状态和持久化。2.TasksView.vue负责页面级编排这次页面层做了两件关键事情当当前列表是卡片视图时才显示TaskListGroupingSettings把taskListGroupingMode和paginatedTaskGroups传给TaskCardList这里非常值得学习页面层不是在“堆组件”。它真正做的是条件编排状态分发多个展示能力之间的协调这就是页面层最核心的职责。3.TaskCardList.vue升级成“平铺 / 分组”双模式这次TaskCardList没有改成两个完全不同的组件而是做了一次很典型的“模板统一化”处理先把平铺模式整理成一个假的单分区再把按状态分组模式整理成真实多分区模板统一循环渲染cardSections这样做的好处是少写一套重复模板单卡片结构只维护一份勾选、编辑、删除逻辑不用拆两份这是一种很实用的前端技巧先把数据结构统一再让模板保持简单。这一课最值得你学会的前端思想1. “分组”是展示组织不是数据过滤很多后台系统都会同时出现筛选排序分页分组你一定要学会把它们分开筛选决定保留哪些数据排序决定数据先后顺序分页决定当前页取哪一段分组决定当前这一段怎么组织展示只要这一层你分清楚后面做看板分列时间线分段日志按日期分组都会顺很多。2. 页面级状态应该高于展示组件这一课我们仍然没有把分组模式状态塞进TaskCardList组件内部。因为它不是“这个组件自己一时兴起的状态”而是页面级偏好要持久化要被页面层协调这说明真正稳定、真正重要的状态应该放在页面级 composable而不是最终渲染组件内部3. 同一批数据可以先分页再分组很多初学者会天然以为先分组再分页但真实后台里不一定这样。这一课故意选择先分页再分组是为了让你认识到前端的数据处理顺序不是固定教条而是由产品语义决定的。当前这节课的产品语义是分页仍然表示“当前页看到哪几条任务”分组只是“这几条任务怎么读起来更清楚”所以先分页再分组是合理的。这一课补了哪些测试1. 单元测试文件src/composables/__tests__/useTasksPage.spec.ts新增覆盖从localStorage恢复合法卡片分组模式非法分组模式自动回退成none标准化结果写回本地存储切换分组模式后页面状态是否正确联动paginatedTaskGroups是否只基于当前页任务生成这一层主要验证页面级偏好状态是否正确分组计算边界是否正确2. E2E 测试文件e2e/pages/TasksPage.tse2e/app.spec.ts新增覆盖切到卡片视图切到“按状态分组”断言卡片分组标题真实出现刷新页面再次断言分组模式和分组标题仍然保留这一层主要验证不只是状态值变了卡片列表结构也真的按状态分区了持久化偏好在真实浏览器里确实能恢复这一课改了哪些文件src/types/task.tssrc/composables/useTasksPage.tssrc/components/tasks/TaskListGroupingSettings.vuesrc/components/tasks/TaskCardList.vuesrc/views/TasksView.vuesrc/composables/__tests__/useTasksPage.spec.tse2e/pages/TasksPage.tse2e/app.spec.tsdocs/32-task-card-grouping-by-status-and-persistence.mddocs/README.md这一课最值得你真正记住什么如果你只记住“多了一个按状态分组按钮”那还不够。你更应该记住下面这 6 点分组不等于筛选分组只是展示组织方式。展示偏好通常更适合放进localStorage而不是 URL。这节课的分组语义是“对当前页任务分组”不是“对全部结果分组”。页面级状态应该放在 composable而不是塞进最终渲染组件内部。当两种展示模式共享同一套卡片结构时优先统一数据结构而不是复制两套模板。真正好的后台列表能力不只是能点通还要能持久化、可测试、边界清晰。这一课的验证命令完成后至少应该验证npmrun test:unit ----runnpmrun type-checknpmrun lintnpmrun test:e2e ----projectchromium一句话总结这一课真正要学会的是任务卡片“平铺显示 / 按状态分组”不是一个简单视觉开关而是一种典型的后台展示偏好能力你要学会把它和筛选、排序、分页分层处理再用页面级状态、统一数据结构、条件编排和 localStorage 持久化把它做成真正可维护的任务页能力。