当前位置: 首页 > news >正文

第 29 课:任务页筛选方案预设与快捷视图

第 29 课:任务页筛选方案预设与快捷视图

这一课,我们继续沿着任务管理页主线往下走,把它从“能筛选”推进到“能复用工作台”:

让用户把当前筛选条件保存成方案,以后可以一键切回。

这一步很像真实后台系统里常见的:

  • 我的待处理
  • 待评审优先处理
  • 高优先级任务池
  • 本周跟进项

很多初学者会把这类功能理解成“多存几组条件”,但真正重要的是:

  • 哪些是当前页面的临时状态?
  • 哪些是用户想长期复用的工作台?
  • 它们应该怎么和 URL、localStorage 一起协同?

这一课一句话在做什么?

这一课我们完成了 6 件事:

  1. 给任务页增加“筛选方案预设”本地持久化。
  2. 允许把当前关键字、状态、优先级和排序保存成一条命名方案。
  3. 支持应用已保存方案,并自动回到第一页。
  4. 支持删除方案,并在删除最后一条时清空本地存储。
  5. 补了“回到默认工作视图”动作,让临时筛选能一键复位。
  6. 补上单元测试、E2E 和文档。

这一课最重要的设计结论

这一课最重要的结论是:

临时筛选状态,不等于可复用工作台。

为什么?

1. 临时筛选状态是“当前这次页面访问”

例如你现在临时把任务页切成:

  • 状态:待开始
  • 优先级:高
  • 排序:截止日期从近到远

这更像:

  • 当前页面状态
  • 当前正在看的结果
  • 适合写进 URL

因为它需要:

  • 刷新恢复
  • 链接分享
  • 浏览器前进后退保留

2. 筛选方案是“以后还想反复使用的工作台”

如果你觉得这套筛选条件以后经常会用到,那它就不再只是当前场景,而是:

  • 一个可复用视图
  • 一个工作台入口
  • 一个个人习惯

所以它更适合放进:

  • localStorage

而不是只停留在当前 URL 里。


3. 应用筛选方案后,当前真实页面状态仍然要同步回 URL

这也是这一课特别值得记住的一点。

筛选方案本身是本地偏好,
但一旦你点击“应用方案”,它就变成了:

  • 当前页面真实生效的筛选状态

所以应用方案后,页面仍然要把:

  • keyword
  • status
  • priority
  • sort

继续同步进 URL。

这和上一课“默认排序偏好”的原则是完全一致的。


这一课在useTasksPage里做了什么?

文件:

  • src/composables/useTasksPage.ts

这一课的核心依然在任务页组合式函数里。

因为:

  • 筛选方案本质上是页面级用户偏好
  • 它依赖当前筛选状态
  • 它还要和默认工作视图、分页、URL 同步一起配合

这些逻辑不适合丢进单个组件里各自维护。


新增了筛选方案的类型和本地存储 key

这次新增了:

  • TaskFilterPreset
  • TASK_TABLE_FILTER_PRESETS_STORAGE_KEY

方案里保存的是一整套筛选快照:

  • keyword
  • statusFilter
  • priorityFilter
  • sortOption

这里要注意:

  • 没有把页码存进去
  • 也没有把分页大小、显示列存进去

为什么?

因为这一课聚焦的是:

  • 筛选与排序工作台

而:

  • 页码是当前浏览位置
  • 分页大小、显示列属于另外两种个人偏好

它们虽然都和“列表体验”有关,但不是同一层语义。


新增了标准化和比较函数

这一课补了几类重要辅助函数:

  • 关键字标准化
  • 状态筛选标准化
  • 优先级筛选标准化
  • 方案名称标准化
  • 方案快照比较函数
  • 本地方案恢复与写回函数

这类函数的意义不是“为了代码看起来高级”,而是:

不要直接相信 localStorage 里的数据永远干净。

只要是本地存储,就要默认考虑下面这些情况:

  • 老版本数据结构
  • 用户手动改过
  • 异常写入
  • 重复名称
  • 空名称

所以这一课继续延续我们前面反复练的模式:

先读 -> 再校验 -> 再标准化 -> 再使用


把“当前筛选快照”和“已保存方案”明确分开

这一课新增了一个很关键的概念:

  • currentTaskFilterPresetSnapshot

它表示:

  • 当前页面正在使用的这一组筛选条件

而:

  • taskFilterPresets

表示:

  • 用户已经保存下来的可复用方案列表

这两者不能混在一起。

因为:

  • 当前快照是实时状态
  • 已保存方案是持久化工作台

只有分开,后面我们才能判断:

  • 当前是不是命中了某条已保存方案
  • 当前是不是默认工作视图
  • 同名保存时应该更新还是新增

新增了几个真正有业务语义的动作函数

例如:

  • saveCurrentTaskFilterAsPreset()
  • applyTaskFilterPreset()
  • deleteTaskFilterPreset()
  • resetTaskFiltersToDefaultView()

这几个函数非常值得你注意。

因为它们已经不是单纯的“改一个 ref”,而是在表达真实的业务动作:

  • 保存一套工作台
  • 切换到一套工作台
  • 删除一套工作台
  • 回到默认工作台

这说明你的composable已经越来越像:

  • 页面领域层

而不只是“顺手抽几个函数”。


为什么“回到默认工作视图”很重要?

这一课除了筛选方案本身,还补了一个非常真实的后台动作:

  • 回到默认工作视图

这个动作背后的设计是:

  • 关键字清空
  • 状态回到全部
  • 优先级回到全部
  • 排序恢复成当前defaultSortOption
  • 页码回到第一页

这一步非常关键,因为它把第 28 课和第 29 课真正串起来了:

  • 第 28 课定义了“默认工作视图”的排序偏好
  • 第 29 课开始让页面具备“工作台切换”能力

这样一来,“默认工作视图”就不再只是说明文字,而是一个真实可回退的页面状态。


这一课在界面层做了什么?

文件:

  • src/components/tasks/TaskFilterPresetsPanel.vue
  • src/views/TasksView.vue

这一课新增了一个独立组件:

  • TaskFilterPresetsPanel

为什么单独拆?

因为如果继续把这块逻辑塞进TaskFilterBar,它会越来越像一个“大而全”的超级组件。

而现在分开后:

  • TaskFilterBar负责临时筛选输入
  • TaskFilterPresetsPanel负责工作台方案管理
  • TasksView负责消息提示和确认框
  • useTasksPage负责真正的状态和行为

这就是一套比较清晰的分层。


页面层负责什么?

这一课里,页面层主要负责:

  • 弹出“保存筛选方案”输入框
  • 弹出“删除筛选方案”确认框
  • 给出成功/失败消息提示

这和我们前面处理删除任务、批量删除、恢复默认排序时的策略是一致的:

  • 页面层负责交互反馈
  • 组合式函数负责业务状态

这一课补了哪些测试?

1.useTasksPage.spec.ts

新增覆盖:

  • localStorage恢复筛选方案
  • 非法和重复方案清理
  • 保存当前筛选为方案
  • 同名方案更新
  • 应用方案后恢复筛选与排序
  • 应用方案后页码回到第一页
  • 回到默认工作视图
  • 删除最后一条方案后清空本地存储

这一层测试主要在验证:

  • 状态边界
  • 本地持久化边界
  • 方案比较与更新规则

2.e2e/app.spec.ts

新增覆盖:

  • 设置状态筛选、优先级筛选和排序
  • 保存筛选方案
  • 回到默认工作视图
  • 再次应用方案
  • 验证 URL 查询参数同步
  • 验证真实任务结果变化
  • 重新进入干净任务页地址后方案仍然存在
  • 删除方案后从界面中消失

这一层测试主要在验证:

  • Element Plus 下拉框真实交互
  • 方案面板真实点击流程
  • localStorage 持久化是否真的生效

这一课改了哪些文件?

  • src/types/task.ts
  • src/composables/useTasksPage.ts
  • src/components/tasks/TaskFilterPresetsPanel.vue
  • src/views/TasksView.vue
  • src/composables/__tests__/useTasksPage.spec.ts
  • e2e/pages/TasksPage.ts
  • e2e/app.spec.ts
  • docs/29-task-filter-presets-and-quick-views.md
  • docs/README.md

这一课最值得你真正学会什么?

如果你只记住“多了一个保存筛选方案的按钮”,那还不够。

你更应该记住下面这 6 点:

  1. 当前页面筛选状态和可复用工作台不是一回事。
  2. 临时状态更适合进 URL,可复用方案更适合放在本地持久化。
  3. 方案保存的是“筛选快照”,不是所有列表偏好都往里塞。
  4. 同名方案更新、非法数据清理、重复项去重,都是本地持久化里很常见的真实工程问题。
  5. 应用方案后,当前真实页面状态仍然要同步到 URL。
  6. 页面层和组合式函数的职责分层,决定了这类复杂交互能不能长期维护。

这一课的验证结果

这一课相关改动完成后,应至少通过:

  • npm run test:unit -- --run
  • npm run type-check
  • npm run lint
  • npm run test:e2e -- --project=chromium
http://www.jsqmd.com/news/664135/

相关文章:

  • Ryujinx模拟器终极指南:在PC上畅玩Switch游戏的完整教程
  • 3分钟搞定!R3nzSkin国服特供版:让你的LOL英雄瞬间穿上新衣
  • 电磁兼容测试与合规性设计实战指南
  • 数据可视化中的度量格式化技巧
  • 专业NCM文件解密指南:高效解锁网易云音乐加密音频的完整解决方案
  • 软件工程-热重载:从原理到实战,解锁高效开发新姿势
  • 告别Sass安装噩梦:从版本陷阱到Dart-Sass迁移的终极避坑指南
  • Kruskal算法的正确实现与哈希集的使用
  • 终极小说下载神器:3步轻松实现200+网站的离线阅读
  • 【AGI技术路线图权威解码】:20年AI架构师亲授从LLM到通用智能的5大跃迁节点与避坑指南
  • 从霍尔信号到单片机引脚:一份被忽略的FOC硬件“避坑”清单(含三极管电平转换与RC滤波实战)
  • Flutter编译报错:Could not resolve依赖的深层解析与镜像源配置实战
  • 别只盯着main.c!揭秘TI C2000 DSP启动时,那些“看不见”的库文件(boot28.asm/args_main.c)都干了啥
  • 0. 工具使用
  • SensitivityMatcher:免费终极游戏鼠标灵敏度精准转换工具完整指南
  • CSS 分组和嵌套
  • 2026年50英寸电视选购指南:多品牌推荐及价格、功能全解析!
  • 嵌入式菜单设计新思路:如何用结构体链表管理STM32的OLED多级菜单?
  • 数字音频压缩技术:从心理声学模型到编码实践
  • jQuery 效果- 隐藏和显示
  • 告别AC5!在Keil MDK AC6下为STM32配置printf到串口的完整指南(含__GNUC__和__clang__宏坑点解析)
  • Multi-Agent 商业化瓶颈突破:如何解决客户付费意愿低的问题?
  • FDC2214电容传感实战:用Arduino+ESP32做个非接触式水位监测器
  • OmenSuperHub终极指南:三步解锁惠普游戏本隐藏性能,告别官方软件束缚
  • C++实现分布式集群聊天服务器
  • **基于ARKit的增强现实手势交互开发实战:从零构建沉浸式用户界面**在移动设备日益智能化的今天,**ARKit(
  • Node.js 与 MySQL 的深入探讨
  • Java+YOLOv11实战:彻底解决工业产线光照不均导致的识别误差
  • 如何计算SQL日期差值_使用DATEDIFF函数实现逻辑判断
  • UOS系统装LibreOffice总报错?实测解决‘权限不足’和‘应用商店安装失败’的3种方法