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

第 37 课:任务详情抽屉上一条 / 下一条切换

第 37 课:任务详情抽屉上一条 / 下一条切换

这一课我们继续沿着“任务管理页主线”往后推进,把上一课已经做好的“任务详情抽屉”再往真实后台系统推进一步。

这次的目标很明确:

  • 在任务详情抽屉里增加“上一条 / 下一条”切换
  • 不离开当前页面,不跳转详情页
  • 切换时继续保持taskId地址栏同步
  • 刷新后仍然能恢复到当前详情任务
  • 补上单元测试、E2E 测试和课程文档

这一课一句话在做什么?

这一课我们让“任务详情抽屉”从“只能看当前一条任务”升级成“可以沿着当前工作上下文继续向前 / 向后处理任务”。

更准确地说,是这句话:

详情抽屉里的上一条 / 下一条,不应该按原始数组乱跳,也不应该只按当前页切片跳,而应该按“当前筛选 + 当前排序后的结果”来跳。

这句话是这节课最重要的工程结论。


为什么后台系统里很常见这个能力?

很多后台页面里,用户并不是只看一条任务,然后就结束。

更常见的是这种流程:

  1. 在列表里筛出一批任务
  2. 打开其中一条看详情
  3. 看完后顺手切到下一条继续处理
  4. 一直保持在同一个工作上下文里

这比“看完一条就关抽屉,再回列表,再点下一条”更顺。

所以这节课本质上不是多加两个按钮,而是在训练你理解:

  • 什么叫“当前工作上下文”
  • 什么叫“上下文内导航”
  • 为什么导航顺序必须和用户当前看到的任务顺序一致

这节课最关键的设计结论

1. 详情导航要基于sortedTasks

这次我们没有把详情抽屉导航基于:

  • 原始tasks
  • 当前页paginatedTasks

而是基于:

  • sortedTasks

原因很重要:

  • tasks只是原始数据顺序,不一定等于用户当前看到的顺序
  • paginatedTasks只是当前页切片,太窄了,翻页后的任务就不在导航上下文里
  • sortedTasks才是“当前筛选 + 当前排序后的完整结果”

也就是说:

详情抽屉切换的是当前结果集里的相邻任务,不是当前分页切片里的相邻任务。

这才更符合后台系统里“保持工作上下文连续”的体验。

2. 详情抽屉仍然只是展示层

这次TaskDetailDrawer.vue只做两件事:

  • 显示当前位置摘要
  • 抛出“上一条 / 下一条”的事件

它不自己决定要切到哪条任务。

真正的详情上下文仍然在页面级useTasksPage.ts里管理。

这说明一个很重要的分层原则:

子组件表达用户意图,页面级 composable 管理真实业务状态。

3. 新入口继续复用旧逻辑

这次新增了:

  • openPreviousTaskDetail()
  • openNextTaskDetail()

但它们最后仍然复用已有的:

  • openTaskDetail(task)

这说明我们没有重新发明一套详情打开逻辑,而是在已有页面级状态基础上扩展入口。

这就是健康的工程演进方式。


这次主要改了哪些文件?

这节课主要改了 7 个地方:

  1. src/composables/useTasksPage.ts
  2. src/views/TasksView.vue
  3. src/components/tasks/TaskDetailDrawer.vue
  4. src/composables/__tests__/useTasksPage.spec.ts
  5. e2e/pages/TasksPage.ts
  6. e2e/app.spec.ts
  7. docs/README.md

另外新增了本节文档:

  • docs/37-task-detail-drawer-prev-next-navigation.md

useTasksPage.ts里学什么?

文件:

  • src/composables/useTasksPage.ts

这次在页面级 composable 里新增了 6 个和详情导航直接相关的状态 / 动作:

  • taskDetailNavigationTasks
  • activeTaskDetailPosition
  • activeTaskDetailTotalCount
  • hasPreviousTaskDetail
  • hasNextTaskDetail
  • openPreviousTaskDetail()
  • openNextTaskDetail()

其中最关键的是这句思路:

先把当前可切换任务集合定义清楚,再谈上一条 / 下一条。

1.taskDetailNavigationTasks

它直接复用了sortedTasks

意思是:

  • 先筛选
  • 再排序
  • 然后把这份结果当成详情抽屉的线性导航上下文

2.activeTaskDetailPosition

它把当前详情任务在导航结果里的索引转成更适合展示的“第几条”。

这里有一个细节很值得学:

  • 找得到任务时:返回1 ~ N
  • 找不到任务时:返回0

这让 UI 层可以明确地区分:

  • 当前任务正常位于结果里
  • 当前任务已经不在当前筛选结果里

3.hasPreviousTaskDetail/hasNextTaskDetail

这两个计算属性负责让抽屉里的按钮天然知道:

  • 什么时候该启用
  • 什么时候该禁用

这样模板层就不需要自己算边界。

4.openPreviousTaskDetail()/openNextTaskDetail()

这两个函数没有自己手写一套“切换详情状态”的新逻辑。

它们做的事很简单:

  1. 根据当前位置拿到目标任务
  2. 校验目标任务存在
  3. 复用openTaskDetail(task)

这说明:

新功能优先扩展旧路径,而不是复制旧路径。


TaskDetailDrawer.vue里学什么?

文件:

  • src/components/tasks/TaskDetailDrawer.vue

这一课里,详情抽屉主要新增了两类能力。

1. 新增导航相关 props

这次抽屉接收了:

  • currentPosition
  • totalCount
  • hasPrevious
  • hasNext

这些都不是抽屉自己算的,而是父层传进来的。

这能说明一个非常重要的组件设计原则:

展示组件尽量消费外部状态,而不是自己偷偷推导业务上下文。

2. 新增导航相关 emits

这次抽屉新增了:

  • previous
  • next

用户点击按钮后,抽屉只负责告诉父组件:

  • 我想切到上一条
  • 我想切到下一条

它不直接改activeTaskDetailId

这说明:

子组件负责“发意图”,父组件和 composable 负责“改状态”。

3. 新增当前位置摘要

这次抽屉顶部增加了一块位置摘要,例如:

  • 第 2 / 3 条

这块 UI 看起来很小,但表达的是很重要的上下文信息:

  • 当前不是孤立的一条任务
  • 当前任务是整套结果里的第几条
  • 用户能预期自己还能往前还是往后处理

这类信息密度很符合后台系统风格。


TasksView.vue里学什么?

文件:

  • src/views/TasksView.vue

页面层这次做的事情不复杂,但很关键:

  1. useTasksPage()里拿出导航相关状态
  2. 把这些状态传给TaskDetailDrawer
  3. @previous/@next事件接回页面级动作

注意这里一个很值得你形成习惯的点:

如果页面层不需要额外提示、不需要额外分支,它可以直接把 composable 动作挂到模板事件上。

比如这次:

  • @previous="openPreviousTaskDetail"
  • @next="openNextTaskDetail"

这说明页面层不一定每次都要包一层函数。

什么时候要包?

  • 需要ElMessage
  • 需要确认框
  • 需要做额外校验

什么时候可以直接挂?

  • 已有动作已经足够表达这次意图

单元测试这次测了什么?

文件:

  • src/composables/__tests__/useTasksPage.spec.ts

这次新增了两组重点测试。

1. 验证导航遵循当前排序顺序

这组测试先把任务排序切成:

  • 截止日期从近到远

然后打开排序结果里的中间任务,再验证:

  • 上一条切到的是排序后的上一条
  • 下一条切到的是排序后的下一条

这很重要,因为它确保我们不是按原始数组乱跳。

2. 验证导航限制在当前筛选子集里

这组测试把状态筛选切到:

  • 待开始

让详情导航上下文收敛成:

  • 4 / 5 / 6

然后验证:

  • 第一条不能再往前
  • 中间项可以前后切换
  • 最后一条不能再往后

这说明我们真的把“详情导航上下文”约束在当前结果集里了。


E2E 这次测了什么?

文件:

  • e2e/pages/TasksPage.ts
  • e2e/app.spec.ts

这次新增了详情导航相关 Page Object 方法:

  • expectTaskDetailPosition()
  • openPreviousTaskDetail()
  • openNextTaskDetail()

然后补了一条完整 E2E 测试链路:

  1. 先筛到待开始
  2. 打开第 5 条任务详情
  3. 断言当前位置是第 2 / 3 条
  4. 切到下一条,变成第 6 条
  5. 再切回上一条,回到第 5 条
  6. 再切到上一条,回到第 4 条
  7. 验证每一步taskId都会跟着改
  8. 刷新页面
  9. 验证详情抽屉、位置摘要、查询参数都能恢复

这条测试链路同时覆盖了:

  • 真实按钮点击
  • 详情切换
  • 地址栏同步
  • 刷新恢复
  • 当前筛选上下文保持稳定

你现在真正应该学会什么?

如果你学完这一课,只记住“加了两个按钮”,其实远远不够。

你更应该真正学会下面这 4 件事:

1. 上一条 / 下一条本质上是“上下文导航”

它不是普通按钮,也不是单纯的 UI 特效。

它表达的是:

用户正在沿着当前结果集继续工作。

2. 导航顺序必须和用户当前视角一致

这也是为什么这次必须基于:

  • 当前筛选
  • 当前排序

而不是原始数组。

3. 分页切片不等于导航上下文

这节课很适合你建立一个高级一点的前端意识:

  • paginatedTasks是页面显示切片
  • sortedTasks是当前完整结果集
  • 详情导航应该更接近结果集,而不是更接近页面切片

这是很典型的“不同状态有不同职责”。

4. 新功能优先复用旧动作

这次上一条 / 下一条最后都复用了:

  • openTaskDetail(task)

说明真正好的代码结构,不是每来一个功能就多写一套逻辑,而是能自然扩展已有路径。


这一课完成后,任务页又更像真实后台了吗?

是的,而且这一步很关键。

现在这个任务页已经不只是:

  • 能筛选
  • 能排序
  • 能分页
  • 能看详情

而是开始具备一种真实后台常见的“连续处理体验”:

  • 打开一条
  • 看完继续切下一条
  • 不中断上下文

这已经非常接近真实业务里的审核台、工单台、任务处理台体验了。

http://www.jsqmd.com/news/689086/

相关文章:

  • 别再为微调大模型发愁了!用LoRA+百川7B,单张消费级显卡也能玩转指令微调
  • Python学习超简单第八弹:网络编程
  • 策略模式的思想的经典案例分析
  • 【AI智能体】Claude Code 集成Github CLI 实现高效项目协同使用详解
  • 谷歌神经机器翻译GNMT:从技术原理到行业变革
  • 一个异或的性质
  • FastAPI在MLOps中的安全认证实践与优化
  • 如何集成Hermes Agent/OpenClaw?2026年阿里云及Coding Plan配置保姆级攻略
  • 中医AI智能诊疗系统:7步免费部署仲景大语言模型的完整指南
  • 2026指纹浏览器与AI风控对抗技术实践:动态环境适配与行为模拟的完整方案
  • Windows系统优化新思路:告别手动调整,用WinUtil实现一键智能管理
  • 厦大847信号与系统状元447分上岸信院经验贴!
  • 2026年Hermes Agent/OpenClaw如何安装?阿里云及Coding Plan配置详细解读
  • ESP32通过WiFi+SBUS协议控制INAV飞控完整教程
  • 为什么越来越多女性创业者选择“玫瑰工程”?一个运营十五年的社区健康品牌深度解析 - GrowthUME
  • 华为MateBook 16重装Win10后,我这样配置开发环境(含软件清单与D盘路径规划)
  • 美的智能家电本地控制终极指南:告别云端依赖,享受稳定智能生活
  • 用InsightFace搞定人脸3D关键点检测:从68点到106点,再到姿态角Pitch/Yaw/Roll的实战解析
  • 浏览器指纹反检测技术深度解析——从内核层防护到行为拟真的全链路实现
  • 华北理工大学怎么样?从办学层次、学科特色、科研实力与升学优势详解
  • 2026年,邯郸性价比高的助贷公司哪家靠谱?一文为你揭晓答案! - GrowthUME
  • 避坑指南:RH850 RS-CANFD中断那些容易搞错的细节(附BusOff处理与FIFO配置)
  • Qt串口通信GUI卡顿?试试把QSerialPort丢到子线程里(附完整代码)
  • pheatmap进阶玩法:手把手教你用聚类结果反向导出排序后的数据表格
  • TensorRT-LLM中KV缓存优化技术解析与实践
  • 中国药科大学赵玉成、徐健/皖西学院韩邦兴ACS Catal|元胡中痕量高效镇痛活性成分左旋紫堇达明生物合成最后缺失步骤的解析(附招聘信息)
  • 关于 CSS 打印你应该知道的样式配置
  • 灰度发布在Agent迭代中的实践:流量分配、效果评估与快速回滚
  • 【JAVA网络面经】网络模型(OSI+TCP/IP)
  • 杂题选讲 2026.4.23 (5)