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

第 36 课:任务详情抽屉快捷改状态

第 36 课:任务详情抽屉快捷改状态

这一课我们继续沿着“任务管理页主线”往后推进,把上一课做好的“任务详情抽屉”从“只能看”升级成“可以就地处理”。

这次的目标很明确:

  • 在任务详情抽屉里直接切换任务状态
  • 不需要先回到表格或切到看板
  • 刷新后状态仍然保留
  • 补上单元测试、E2E 测试和课程文档

这一课一句话在做什么?

这一课我们把任务详情抽屉升级成了一个真正后台常见的“轻操作工作区”:

用户可以在查看任务详情的同时,直接把任务改成另一个状态,而且这一切仍然复用页面级任务状态逻辑。

这件事看起来只是多了几个按钮,但工程上它很重要,因为它训练你理解下面这件事:

一个功能入口可以有很多个,但真正改数据的核心逻辑最好只有一份。


为什么要在详情抽屉里做“快捷改状态”?

前面我们已经有两种和任务状态相关的入口:

  • 批量改状态
  • 看板里拖拽改状态

但真实后台里还经常会有第三种入口:

  • 打开单条记录详情后,顺手改状态

为什么这很常见?

1. 它符合“先看详情,再做决定”的工作流

用户很多时候不是一进列表就知道该把状态改成什么,而是要先看:

  • 任务标题
  • 负责人
  • 截止日期
  • 描述内容

看完后再决定:

  • 继续推进
  • 提交评审
  • 标记完成

如果这时还要用户退出详情,再回表格找按钮,体验就很割裂。

2. 它属于后台里的“就地处理”

后台系统常见原则之一是:

尽量让用户在当前上下文里完成动作,而不是频繁切页面。

任务详情抽屉已经把上下文保留下来了,所以把“轻量状态流转”也放进去,是很自然的演进。

3. 它能训练你做“多入口复用同一套业务逻辑”

这节课最值得你学的,不是按钮怎么写,而是:

  • 看板拖拽能改状态
  • 详情抽屉按钮也能改状态
  • 但它们都不各自维护一份状态更新逻辑

它们最后都走同一个页面级函数。

这就是工程里很重要的“避免重复业务逻辑”。


这一课最关键的设计结论

这次我们没有把“详情抽屉改状态”写成一套独立逻辑,而是做了这一层关系:

  • TaskDetailDrawer.vue
    只负责展示按钮,并向上抛出“用户想改成哪个状态”
  • TasksView.vue
    负责接收事件、调用页面级逻辑,并给用户提示消息
  • useTasksPage.ts
    负责真正修改任务状态

也就是说:

子组件发意图,页面层做协调,composable 改数据。

这是 Vue 项目里非常重要的结构习惯。


这一课改了哪些文件?

这次主要改了 6 个地方:

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

最后还新增了本文档,并更新了docs/README.md


TaskDetailDrawer.vue里学什么?

文件:

  • src/components/tasks/TaskDetailDrawer.vue

这一课里,详情抽屉组件新增了两件事:

1. 新增statusOptions属性

父组件会把所有合法任务状态传下来,抽屉组件只负责渲染,不自己硬编码状态列表。

这说明一个设计原则:

展示组件尽量消费外部传入的数据,而不是偷偷依赖业务常量。

这样做的好处是:

  • 组件更通用
  • 更好测试
  • 更容易和页面级逻辑保持一致

2. 新增change-status事件

点击“改为进行中 / 改为待评审 / 改为已完成”这些按钮时,抽屉组件不会自己改任务数据,而是向父组件抛事件。

这说明:

子组件负责表达用户意图,不直接篡改父层业务状态。

这对初学者很关键。

你要慢慢形成这个判断:

  • 如果是表单输入、按钮点击、开关切换
    子组件可以发事件
  • 如果是真正的数据源更新
    应该交给页面层或 composable

3. 新增“当前状态 + 快捷按钮区”

这一块 UI 做了两层信息:

  • 当前:xxx
  • 改为 xxx

这样比只放一排按钮更清楚,因为用户先看到“当前是什么”,再决定“下一步要改成什么”。

这属于非常典型的后台交互表达方式。


useTasksPage.ts里学什么?

文件:

  • src/composables/useTasksPage.ts

这一课在页面级 composable 里新增了:

  • changeActiveTaskDetailStatus(nextStatus)

它做的事情很简单:

  1. 先判断当前是否真的有打开中的详情任务
  2. 如果没有,直接返回false
  3. 如果有,就复用已有的moveTaskToStatus(taskId, nextStatus)

注意这里最关键的不是“代码短”,而是:

详情抽屉没有重新发明一套状态更新逻辑,而是复用了页面已经存在的单条改状态能力。

这就是为什么前面课程里一直强调:

  • 页面级状态要集中
  • 公共业务动作要收口

因为当新入口出现时,你就能很自然地复用。


TasksView.vue里学什么?

文件:

  • src/views/TasksView.vue

页面层新增了一个处理函数:

  • handleChangeActiveTaskDetailStatus(nextStatus)

它主要负责三类事情:

1. 做前置校验

比如:

  • 当前有没有详情任务
  • 用户点的是不是当前已经处于的状态

这类校验适合放页面层,因为它和用户提示文案强相关。

2. 调用 composable 真正修改状态

页面层不直接改数组,而是调用:

  • changeActiveTaskDetailStatus(nextStatus)

这让页面层保持“协调者”角色。

3. 给出成功或失败提示

ElMessage.success(...)这样的界面提示,通常更适合留在页面层。

这也是我们前面多次强调的分层方式:

  • composable:负责逻辑与状态
  • 页面层:负责交互反馈

这一课的状态为什么刷新后不会丢?

因为我们这次没有新造一套状态源。

详情抽屉改状态最终仍然会走:

  • 本地任务数组更新
  • 写回任务数据源

而上一课已经把详情抽屉与taskId查询参数同步好了,所以刷新后会发生两件事:

  1. taskId让详情抽屉重新恢复到同一条任务
  2. 数据源里已经是最新状态,所以详情抽屉看到的也是最新结果

也就是说:

上一课解决“刷新后还能打开到哪条任务”,这一课解决“打开后看到的是最新状态”。

这两课是严格连在一起的。


单元测试测了什么?

文件:

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

这次新增的单测重点不是测按钮,而是测页面级逻辑:

  • 打开任务详情
  • 在详情上下文里改状态
  • 改完后详情 id 不丢
  • 抽屉可见状态不丢
  • 当前详情任务状态同步更新
  • 本地任务数组同步更新
  • updateTask被正确调用
  • 重复改成同一状态时不会重复写回

这说明一个很重要的测试思想:

单元测试优先测状态变化和业务规则,不优先测视觉层。


E2E 测试测了什么?

文件:

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

这次新增了详情抽屉相关的 Page Object 方法:

  • 断言详情里的当前状态
  • 点击详情里的快捷改状态按钮

然后新增了一条完整 E2E:

  1. 打开第 4 条任务详情
  2. 确认当前状态是“待开始”
  3. 在抽屉里点击“改为进行中”
  4. 断言抽屉状态变了
  5. 断言列表里的状态也变了
  6. 刷新页面
  7. 断言详情抽屉仍然恢复
  8. 断言状态仍然是“进行中”

这条链路很有代表性,因为它同时验证了:

  • 抽屉交互
  • 页面级状态更新
  • 数据持久化
  • 刷新恢复

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

如果你学完这一课,只记住一句代码层面的结论,其实还不够。

你更应该建立下面这几个工程习惯:

1. 新入口不等于新逻辑

一个功能新增入口时,先问自己:

  • 这是一个新功能吗?
  • 还是旧功能的新入口?

如果是后者,优先复用。

2. 组件通信先传“意图”,不要直接传“数据操作”

像这次的详情抽屉,更好的表达是:

  • “我想改成进行中”

而不是:

  • “我自己去改任务数组”

3. 页面层是协调层,不是数据仓库

页面层适合:

  • 接事件
  • 做提示
  • 做流程协调

但真正的任务数据变化,最好还是收口到 composable。


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

是的,而且是明显更像了。

现在这个任务页已经具备这些典型后台能力:

  • 列表筛选
  • 分页
  • 排序
  • 视图切换
  • 看板拖拽
  • 详情抽屉
  • 详情内快捷改状态

也就是说,它已经不再是“演示几个 Vue 语法”的页面,而是在逐步靠近真实项目里的任务工作台。


本课你可以自己复盘的问题

建议你现在暂停几分钟,自己回答下面这些问题:

  1. 为什么TaskDetailDrawer不直接修改任务数组?
  2. 为什么changeActiveTaskDetailStatus()要复用moveTaskToStatus()
  3. 为什么“提示消息”更适合留在TasksView.vue
  4. 为什么这次刷新后状态不会丢?
  5. 为什么这是“旧逻辑的新入口”,不是“新功能的新逻辑”?

如果你能把这 5 个问题讲清楚,这一课你就真的吃透了。


本课相关文件

  • src/components/tasks/TaskDetailDrawer.vue
  • src/views/TasksView.vue
  • src/composables/useTasksPage.ts
  • src/composables/__tests__/useTasksPage.spec.ts
  • e2e/pages/TasksPage.ts
  • e2e/app.spec.ts

验证命令

你后面可以自己反复执行这些命令复习:

npmrun lintnpmrun type-checknpmrun test:unit ----runnpmrun test:e2e ----project=chromium-g"detail drawer"
http://www.jsqmd.com/news/689099/

相关文章:

  • 计时器生产降本参考:YL1621选型实测分享
  • IDS的相机在Windows系统上的使用1——Metavision Studio安装(此教程针对)
  • 遥感图像小目标检测太头疼?试试用SuperYOLO结合超分,实测VEDAI数据集效果提升明显
  • 掌握Notepad--:跨平台中文文本编辑器的终极实用指南
  • 基于多任务学习与注意力机制的作物生长状态智能监测与模拟系统
  • 三极管开关电路设计(知识点:多级放大 触摸感应 限流电阻 偏置电阻)笔记
  • 2026年怎么搭建Hermes Agent/OpenClaw?阿里云及Coding Plan配置详细步骤
  • 5分钟掌握League-Toolkit:英雄联盟玩家的智能助手终极指南
  • 继Harness之后,“龙虾”JiuwenClaw率先开启 “Coordination Engineering” 时代
  • Linux 进阶命令实战:sudo 授权、文件查找、文本处理与进程管理
  • 五种高级RAG架构解析:突破传统检索增强生成技术
  • 告别重复劳动:用Excel VBA+SAP GUI脚本,5分钟搞定批量物料价格查询(CKM3N实战)
  • 第 37 课:任务详情抽屉上一条 / 下一条切换
  • 别再为微调大模型发愁了!用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盘路径规划)
  • 美的智能家电本地控制终极指南:告别云端依赖,享受稳定智能生活