第 44 课:任务详情抽屉里的评论输入与操作记录联动

这一课我们继续沿着"任务管理页主线"往前推进。

前面你已经做到:

  • 在任务详情抽屉里查看操作记录、评论和附件
  • 在详情里快捷改状态
  • 在详情里上一条 / 下一条切换
  • 在详情里直接驱动筛选
  • 在详情里建立批量上下文
  • 在详情里直接批量改状态、批量删除

但到第 43 课为止,详情抽屉里的"协作评论"仍然只是只读展示。

也就是说:

  • 你能看已有评论
  • 但还不能在当前任务上下文里直接补一条新评论

所以这一课要补上的核心能力是:

让任务详情抽屉从"只读业务区块展示",升级成"可直接协作输入"的入口。

而且评论提交后,不只评论区要更新:

  • 操作记录区也要同步追加一条"评论协作"记录

这才更像真实后台。


这一课一句话在做什么?

这一课本质上是在做:

把详情抽屉里的评论区从只读列表,升级成"可输入、可提交、可联动"的协作区块。

重点不是简单加一个 textarea。

重点是把下面这条链路真正接起来:

  1. 用户在详情抽屉里输入评论
  2. 页面层校验并接住提交意图
  3. 评论区立即出现新评论
  4. 操作记录区同时追加一条评论协作记录

为什么这个能力很像真实后台?

因为真实后台里的详情抽屉,通常不只是"查看资料"。

它更常承担两类工作:

  1. 看当前记录上下文
  2. 顺手补一条协作信息

比如:

  • 给任务补一条最新判断
  • 记录当前阻塞点
  • 说明下一步准备怎么做
  • 留一条评审意见

如果每次都要:

  • 先离开当前任务详情
  • 再去别的地方找评论入口

体验就很割裂。

所以这一课做的事情非常真实:

让用户在"正在看这条任务"的那个地方,直接把协作输入补进去。


这节课最关键的设计结论

1. 基础详情数据和运行时新增数据要分层

这节课没有直接去改:

  • src/mock/taskDetail.ts

里那份基础 mock 数据。

而是把详情协作数据拆成两层:

  1. 基础层
    • 继续由 getTaskDetailBusinessData(task) 生成
  2. 运行时增量层
    • 当前用户在本次页面会话里新提交的评论
    • 当前用户在本次页面会话里新追加的活动记录

最后再在页面层把两层合并。

这非常重要。

因为你要开始学会区分:

  • "系统初始给我的上下文"
  • "用户当前操作临时追加的上下文"

2. 评论输入框本身可以是展示组件的一部分,但草稿状态最好由页面层托管

这一课里,TaskDetailDrawer.vue 新增了:

  • commentDraft
  • commentAuthor
  • update:comment-draft
  • submit-comment

也就是说:

  • 输入框 UI 在抽屉组件里
  • 但草稿值和真正提交逻辑仍然在页面层

这是一种很经典的写法:

展示组件负责呈现输入入口,页面层负责托管跨区域业务状态。

3. 评论提交后不只评论区变,操作记录区也要同步变

这一课最关键的不是"评论出现了"。

而是:

评论提交本身也应该被视为一条后台操作。

所以提交评论后,页面层会同时创建两份数据:

  1. 一条新的评论记录
  2. 一条新的活动记录

这让详情抽屉里两块区块形成了联动:

  • 评论区展示讨论内容
  • 操作记录区展示"刚刚发生了什么"

4. 这节课先做"当前会话内可见",暂时不做后端持久化

这一课故意没有把评论持久化到后端,也没有写进 localStorage。

这是有意设计,不是没做完。

因为当前更重要的是先让你彻底理解:

  1. 详情基础数据从哪里来
  2. 运行时协作增量放在哪里
  3. 页面层如何统一协调展示层和业务层

如果这三步还没理清,就直接上接口或持久化,代码很容易乱。

所以这一课的范围是:

先把页面内协作输入闭环做对。


这次主要改了哪些文件?

这一课主要涉及这些文件:

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

另外新增了本节文档:

  • docs/44-task-detail-comment-composer-and-activity-sync.md

TaskDetailDrawer.vue 里学什么?

这一课里,评论区不再只是"评论列表 + 空状态提示"。

它前面新增了一块评论输入区。

1. 评论输入区本质上是新的详情工作流入口

这块输入区不是一个普通表单。

它是在告诉你:

详情抽屉可以同时承担"查看上下文"和"补充上下文"两种职责。

这和前面几课是一脉相承的:

  • 快捷改状态,是"就地处理"
  • 快速筛选,是"从详情切回列表上下文"
  • 批量处理,是"从详情发起一批任务动作"
  • 评论输入,是"从详情补充协作信息"

2. 组件继续只抛意图,不自己直接改评论列表

这一课里,抽屉组件新增了:

  • update:comment-draft
  • submit-comment

但它依然没有直接去改:

  • detailData.comments
  • detailData.activityLog

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

详情抽屉可以变得更强,但它依然不应该直接接管页面业务数据。

3. "评论人是谁"也应该在界面上明确展示

输入区不是只有一个 textarea。

还额外展示了:

  • 当前评论人标签

这是一种很真实的后台细节。

因为用户在协作系统里通常会关心:

  • 这条评论最终会以谁的身份发出

TasksView.vue 里学什么?

这一课真正的业务协调核心仍然在页面层。

1. 页面层新增了"运行时评论增量"和"运行时活动记录增量"

页面层这次新增了三组状态:

  • taskDetailCommentDraft
  • taskDetailRuntimeComments
  • taskDetailRuntimeActivityLog

这三组状态分别负责:

  1. 当前评论输入框草稿
  2. 本次会话里新增的评论
  3. 本次会话里新增的评论活动记录

它们都不属于基础任务数据本身。

这就是分层设计。

2. 当前详情业务数据不再只是"直接取 mock"

以前是:

  • getTaskDetailBusinessData(activeTaskDetail)

现在变成:

  1. 先拿基础 mock 详情数据
  2. 再读取当前任务对应的运行时评论增量
  3. 再读取当前任务对应的运行时活动记录增量
  4. 最后合并成真正给抽屉展示的数据

这里你要学会一个很关键的思维:

页面真正展示的数据,常常不是某一个来源,而是多个来源合并后的结果。

3. 评论提交流程要先校验,再创建两类数据

handleSubmitTaskDetailComment 做了几件事:

  1. 检查当前是否有有效详情任务
  2. 检查页面是否正在加载
  3. 检查评论内容是否为空
  4. 生成统一时间文案
  5. 创建评论记录
  6. 创建活动记录
  7. 追加到当前任务对应的运行时增量里
  8. 清空草稿

这说明一个后台动作通常不是"点一下就完了"。

它背后通常是一个小型工作流。

4. 删除任务时要顺手清理这条任务对应的运行时详情协作状态

这一课我还顺手补了一个非常重要的清理动作:

  • 单条删除时清理这条任务的运行时评论 / 活动记录增量
  • 批量删除时批量清理这些增量

这说明一个工程层面的习惯:

你新增了某种按任务 id 挂载的运行时状态,就要同时考虑它的销毁时机。


taskDetailCollaboration.ts 里学什么?

这一课新增了一个纯工具文件:

  • src/utils/taskDetailCollaboration.ts

它负责三类事情:

  1. 格式化详情区时间文案
  2. 创建评论记录
  3. 创建评论活动记录
  4. 合并基础详情数据和运行时增量

为什么值得抽?

因为这些逻辑都属于:

  • 规则明确
  • 不依赖组件实例
  • 很适合单元测试

这正是纯函数最适合承接的部分。


单元测试这次补了什么?

1. taskDetailCollaboration.spec.ts

这一课给新纯函数补了四类验证:

  • 时间文案格式化是否正确
  • 评论记录创建是否正确
  • 评论活动记录创建是否正确
  • 业务数据合并是否正确

这让"评论输入联动"里最容易写错的规则部分先被锁住。

2. taskDetailDrawer.spec.ts

这一课继续补了展示层组件测试:

  • 评论输入区是否渲染出来
  • 是否会抛出 update:comment-draft
  • 是否会抛出 submit-comment
  • 空草稿时是否不会误触发提交

这很适合帮助你区分:

  • 展示层应该测什么
  • 页面层应该测什么

E2E 这次补了什么?

1. Page Object 新增了评论输入语义方法

文件:

  • e2e/pages/TasksPage.ts

新增方法:

  • fillTaskDetailCommentDraft
  • submitTaskDetailComment

同时还顺手把两个已有定位器收紧了:

  • 详情里的"改为某状态"按钮现在按精确文案点
  • 详情评论断言现在只在评论正文节点里找

这说明一个很重要的测试经验:

当页面能力变多时,Page Object 的语义定位也要跟着变精确。

2. 新增了一条完整的评论提交流程 E2E

文件:

  • e2e/app.spec.ts

新增测试:

  • user can add a collaboration comment inside task detail drawer

它验证了:

  1. 打开第 4 条任务详情
  2. 填写一条新评论
  3. 提交评论
  4. 评论区立即出现这条评论
  5. 操作记录区同步出现一条评论协作记录
  6. 关闭再打开同一条任务详情后,这条评论在当前会话内仍然保留

这已经是一个很完整的小闭环了。


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

学完这一课,你最应该记住的是下面 6 件事:

1. 详情抽屉里的业务区块不一定只能只读

它完全可以逐步升级成真正可操作的工作区。

2. "基础详情数据"和"运行时新增数据"最好分层

不要一上来就直接改基础 mock 或把所有东西搅在一起。

3. 输入框可以在展示组件里,但草稿状态不一定要放在展示组件里

这就是"受控组件"思路。

4. 一次评论提交,可能会同时影响多个区块

评论区和操作记录区这次就是联动关系。

5. 新增按任务挂载的运行时状态时,一定要考虑删除清理

否则后面页面会越来越脏。

6. 页面越复杂,测试定位器越要语义清晰、范围明确

否则稍微多一个按钮、多一段重复文案,E2E 就会开始误命中。

相关推荐
ndsc_d1 小时前
前端实战复盘:用AI直接生成响应式官网落地页与React源码
前端·人工智能·react.js·ui·前端框架·aigc·paico
大家的林语冰2 小时前
✌️ Deno 2.9 来了,ESM 直接导入 CSS,甚至能开发桌面应用?!
前端·javascript·node.js
李顿波2 小时前
前端样式技术发展进程和解析(长期更新版)
前端
不简说2 小时前
JS 代码技巧 vol.1 — 10 个让代码少写 30% 的小套路
前端·javascript·面试
Hilaku2 小时前
为什么业务型前端容易遭遇中年危机?
前端·javascript·程序员
এ慕ོ冬℘゜3 小时前
深度解析 JavaScript:赋予 Web 灵魂的“全栈语言”
开发语言·前端·javascript
iCOD3R3 小时前
Skill - 3秒生成精美GitHub主页
前端·程序员·ai编程
爱勇宝3 小时前
《道德经》第5章:生产环境不相信眼泪
前端·后端·架构
掘金者阿豪3 小时前
LEFT JOIN 凭空消失的背后,是优化器偷偷帮你做了决定
前端·后端