第 28 课:任务页排序偏好与默认工作视图

张开发
2026/4/19 7:14:26 15 分钟阅读

分享文章

第 28 课:任务页排序偏好与默认工作视图
第 28 课任务页排序偏好与默认工作视图这一课我们继续沿着任务管理页主线往下走把它再往真实后台系统推进一步让用户不只是临时切换排序还能把当前排序保存成“默认工作视图”。这件事看起来只是多了一个“记住排序”的功能但它背后其实牵涉一个很关键的前端设计问题当前页面状态应该怎么和 URL 协同个人使用偏好又应该放在哪里当两者同时存在时谁的优先级更高这一课一句话在做什么这一课我们完成了 6 件事给任务页增加“默认排序偏好”本地持久化。让用户可以把“当前排序”保存成默认工作视图。让用户可以一键恢复系统默认排序。让任务页在 URL 没有显式sort参数时自动恢复用户自己的默认排序。继续保持“真实当前视图”同步到 URL。补上单元测试、查询同步测试、E2E 和文档。这一课最重要的设计结论这一课最重要的不是按钮本身而是下面这条优先级规则显式 URL sort localStorage 默认工作视图 系统默认排序为什么这样设计1. URL 里的 sort 是“当前场景状态”如果用户现在访问的是/tasks?sortdueDateDesc那就说明这次访问已经明确指定了当前视图应该怎么排。这种状态的特点是可以刷新恢复可以分享给别人可以被浏览器前进后退保留所以它的优先级应该最高。2. localStorage 里的默认排序是“个人习惯”如果用户平时习惯先看截止日期从远到近那这是一种个人使用偏好。这种状态的特点是更像“我的默认打开方式”不一定要分享给别人更适合保存在本机所以它应该放进localStorage而不是直接当成全局业务状态。3. 系统默认排序只是兜底规则如果URL 没给sort用户也没保存过默认工作视图这时候才回退到系统默认排序也就是default这一课在useTasksPage里做了什么文件src/composables/useTasksPage.ts这一课的核心仍然放在任务页组合式函数里因为当前排序是页面状态默认排序偏好也是页面级用户偏好它们都不适合散落到多个组件里各自管理新增了默认排序持久化能力这一课新增了本地存储 keyTASK_TABLE_DEFAULT_SORT_STORAGE_KEY同时补了几类辅助函数排序合法性判断排序标准化函数默认排序读取函数默认排序写回函数排序值转中文文案函数这说明我们已经开始在项目里重复练一种很重要的工程模式读取本地偏好 - 做合法性清理 - 写回标准化结果 - 暴露给页面使用把“当前排序”和“默认排序偏好”拆成了两份状态这是这一课最关键的一点。现在任务页里有两份排序相关状态sortOptiondefaultSortOption它们不是一回事。sortOption表示当前这一次页面访问实际使用的排序方式defaultSortOption表示用户希望以后直接打开任务页时优先使用的默认排序这两份状态拆开以后逻辑会清晰很多你可以临时切换当前排序也可以决定要不要把它保存成默认工作视图还可以恢复系统默认而不会把“当前场景状态”和“个人长期偏好”混成一份状态。新增了几个更有业务语义的计算状态例如currentSortOptionLabeldefaultSortOptionLabelisCurrentSortSavedAsDefaulthasCustomizedDefaultSort这些状态的意义不是“为了少写几行模板”而是让界面层更容易表达业务语义让消息提示更清楚让按钮显隐和禁用规则更直接新增了两个真正有业务意图的动作函数例如saveCurrentSortAsDefaultView()resetDefaultSortPreference()这两个函数很值得你注意。因为它们不再是简单的“修改某个 ref”而是在表达明确的业务动作把当前排序保存成默认工作视图恢复系统默认排序这就是组合式函数越来越像“页面领域层”的表现。这一课在 URL 同步层做了什么文件src/composables/useTaskFilterQuerySync.ts这一课最关键的升级是sort 的默认回退值不再被硬编码成 default。现在它会变成先读 URL 里的sort如果 URL 没有合法sort就回退到defaultSortOption这一步非常重要因为它真正把URL 当前场景状态localStorage 默认工作视图接到一起了。为什么 URL 里最终还是要写回 sort这里很多初学者会疑惑既然默认排序来自 localStorage为什么还要把它重新同步到 URL答案是因为一旦它已经成为“当前真实页面视图”那它就不再只是一个隐形偏好而是当前页面真正生效的状态所以它应该被同步进 URL这样才具备刷新恢复链接分享浏览器历史记录一致性这也是这一课最值得建立的心智模型之一localStorage 可以决定初始值但当前真实页面状态仍然应该由 URL 明确表达。这一课在界面层做了什么文件src/components/tasks/TaskFilterBar.vuesrc/views/TasksView.vue这一课在排序下拉框下面补了一块“默认工作视图”说明区。它做了三件事展示当前默认排序是什么。告诉你当前排序是否已经保存成默认工作视图。提供“设为默认视图”和“恢复系统默认”按钮。这里要重点理解一个分层原则TaskFilterBar只负责展示和抛出事件TasksView负责消息提示useTasksPage负责真正的状态和持久化逻辑这和我们前面反复练习的分层方式是一致的。这一课补了哪些测试1.useTasksPage.spec.ts新增覆盖默认排序偏好恢复非法默认排序清理保存默认工作视图恢复系统默认排序当前排序状态与默认偏好状态分离2.useTaskFilterQuerySync.spec.ts新增覆盖URL 没有sort时使用本地默认排序显式sort查询参数覆盖本地默认偏好非法sort查询参数回退到本地默认排序这一层测试非常关键因为这一课最容易出问题的地方其实不是按钮而是URL 和本地偏好的优先级3.e2e/app.spec.ts新增覆盖先切换排序再保存默认工作视图重新进入不带查询参数的/tasks断言默认排序被自动恢复再恢复系统默认再次进入干净任务页地址断言页面回到系统默认顺序这能验证真正浏览器里最完整的一条用户路径。这一课改了哪些文件src/composables/useTasksPage.tssrc/composables/useTaskFilterQuerySync.tssrc/components/tasks/TaskFilterBar.vuesrc/views/TasksView.vuesrc/composables/__tests__/useTasksPage.spec.tssrc/composables/__tests__/useTaskFilterQuerySync.spec.tse2e/pages/TasksPage.tse2e/app.spec.tsdocs/28-task-sort-preference-and-default-view.mddocs/README.md这一课最值得你真正学会什么如果你只记住“多了一个默认排序按钮”那还不够。你更应该记住下面这 6 点当前页面状态和个人默认偏好往往不是同一份状态。URL 更适合表达当前真实场景本地存储更适合表达个人长期习惯。当两者同时存在时一定要提前定义清楚优先级。localStorage 里的值不能直接信任读取后一定要标准化。一个本地偏好一旦真正生效成当前页面视图就应该同步回 URL。这种“状态分层 优先级规则”的能力一定要同时用单元测试和 E2E 验证。这一课的验证结果这一课相关改动完成后应至少通过npm run test:unit -- --runnpm run type-checknpm run lintnpm run test:e2e -- --projectchromium

更多文章