这一课我们继续做真的页面重构。
这次不是再讲抽象原则,
而是继续把任务页往"清晰组合页"的方向推进。
这次新增的核心组件是:
src/components/tasks/TaskTable.vue
同时更新了:
src/views/TasksView.vue
先讲结论
这次为什么优先拆表格,而不是先拆弹窗?
因为表格满足这三个条件:
- 它已经是一整块独立区域
- 它的输入非常清晰,只需要任务列表
- 它虽然有一点显示逻辑,但状态复杂度仍然可控
而弹窗目前还同时牵涉:
- 弹窗开关
- 表单状态
- 校验
- 提交
- 重置
它的复杂度明显更高,所以不适合比表格更早拆。
这次重构涉及哪些文件
新增文件
src/components/tasks/TaskTable.vue
更新文件
src/views/TasksView.vuedocs/README.md
为什么表格是第二轮最合适的目标
在上一轮重构后,TasksView.vue 还剩下两块明显比较重的区域:
- 任务表格
- 新增任务弹窗
如果继续按照"先简单、后复杂"的策略,
表格显然更合适。
因为表格虽然模板长一点,但它本质上还是:
接收数据 -> 按规则渲染
而弹窗更像:
局部小业务系统
这两者不是一个复杂度等级。
所以这次优先拆表格,是一次很稳的决策。
TaskTable.vue 的职责是什么
当前这个组件的职责非常清楚:
- 接收任务列表
- 渲染表格
- 渲染状态标签
- 渲染优先级标签
- 当列表为空时显示空状态
你会发现,这个组件现在的定位仍然是:
展示型组件为主,附带少量显示规则
它和弹窗最大的区别就在这里。
这个组件的输入是什么
它当前只有一个核心输入:
tasks
也就是说,父组件已经把"筛选后的最终结果"准备好了,
表格组件只负责显示。
这是一种非常理想的结构,因为它让组件边界特别清楚:
- 父组件负责算结果
- 子组件负责画结果
这个组件为什么还保留了两个函数
你会看到 TaskTable.vue 内部有两个辅助函数:
getStatusTypegetPriorityType
这两个函数本质上不是业务逻辑,
而是"展示规则翻译器"。
它们做的是:
- 业务值"已完成" -> UI 颜色
success - 业务值"高" -> UI 颜色
danger
所以把它们放进表格组件是合理的。
因为这些函数描述的是:
表格这一块应该怎么显示
而不是:
页面整体业务该怎么运转
这就是为什么这次我把它们从 TasksView.vue 下沉到了 TaskTable.vue。
这一步很值得你学
很多初学者做组件拆分时容易只会"搬模板",
但不会判断哪些函数也应该一起搬走。
你现在要学会一件事:
如果一个函数只服务某个组件的显示规则,它通常就适合跟着组件一起下沉
这就是更完整的组件化思维。
TasksView.vue 这次又轻了什么
拆表格之后,父组件不再负责:
- 表格列模板
- 状态标签插槽
- 优先级标签插槽
- 空状态显示
- 标签颜色映射函数
它现在更专注于:
- 管主数据
- 管筛选条件
- 管弹窗和表单
- 计算筛选结果
- 计算统计卡片
- 组合子组件
这说明 TasksView.vue 又更像一个"页面容器"了。
现在的任务页已经接近什么结构
现在 TasksView.vue 基本已经有了这种层次:
vue
<TaskPageHeader />
<TaskStatsCards />
<TaskFilterBar />
<TaskTable />
<el-dialog ... />
这意味着:
- 页面头部独立了
- 统计区独立了
- 筛选区独立了
- 表格区独立了
- 当前只剩弹窗还是页面里最重的一块
这就是非常典型的"渐进式收缩父页面"的过程。
为什么 TaskTable.vue 仍然算比较简单
虽然表格看起来行数不少,
但它的复杂度主要来自"模板长度",而不是"状态关系"。
它没有自己单独维护:
- 筛选状态
- 提交状态
- 表单状态
- 打开关闭状态
所以它比弹窗简单得多。
这也是为什么:
模板长,不一定最复杂;状态多,通常才是真的复杂
这是你以后判断重构优先级时非常重要的一条经验。
这次重构最值得你学的设计判断
1. 先拆"输入明确"的区域
表格的输入非常明确:
- 就是任务列表
这种组件最容易设计边界。
2. 展示规则可以跟着展示组件走
状态颜色、优先级颜色这类规则,不一定要永远留在父组件。
如果它们只服务当前展示块,
跟着展示组件一起下沉往往更合理。
3. 父组件不要继续背所有模板细节
父组件越像"总控层",
整个页面就越容易读。
这次重构的实际效果,就是让 TasksView.vue 继续远离"大模板 + 大逻辑"的方向。
这次重构后,你应该怎么理解父子分工
父组件 TasksView.vue
负责:
- 主任务数据
- 筛选条件
- 统计计算
- 新增任务逻辑
- 弹窗逻辑
- 页面级编排
子组件 TaskTable.vue
负责:
- 表格结构
- 标签显示
- 空状态显示
你可以把它们之间的关系理解成:
父组件决定要显示什么,子组件决定怎么显示
这次重构最容易忽略的一个点
有些人会觉得:
"表格只是搬出去,没什么本质变化。"
其实不是。
真正的变化在于:
- 父组件少了一整块模板噪音
- 展示规则开始就近收口
- 页面职责开始更明确
这就是为什么真实项目里,
看起来"只是拆了一个组件",
但长期维护体验会明显不同。
你现在应该能回答的 10 个问题
- 为什么表格比弹窗更适合作为第二轮重构目标?
TaskTable.vue的核心输入是什么?- 为什么它当前仍然算低复杂度组件?
getStatusType和getPriorityType为什么适合下沉到表格组件?- 父组件拆掉表格后,少承担了哪些内容?
- 现在的
TasksView.vue为什么更像页面容器了? - 为什么"模板长"和"状态复杂"不是一回事?
- 什么样的函数适合跟着展示组件一起移动?
- 当前任务页里下一块最重的区域是什么?
- 为什么渐进式重构会让页面越来越清晰?
这节课的动手练习
练习 1
打开 TaskTable.vue,回答:
- 它负责什么
- 它不负责什么
目的:
训练你判断组件边界。
练习 2
对照看:
尝试自己说出:
- 哪些逻辑还在父组件里
- 哪些逻辑已经下沉到子组件里
目的:
训练你看懂"职责迁移"。
练习 3
试着自己判断:
如果以后要给表格加"编辑"按钮和"删除"按钮,
它们更适合:
- 直接写在
TaskTable.vue
还是 - 继续放在
TasksView.vue
并给出理由。
目的:
开始练习"组件未来扩展方向"的判断。
这节课的复习结论
把这次第二轮重构压缩成 8 句话:
- 表格是第二轮重构最合适的对象,因为它边界清晰、输入明确。
TaskTable.vue主要是展示组件,复杂度明显低于弹窗表单。- 父组件继续保留页面级业务和状态管理。
- 子组件负责表格结构、标签显示和空状态。
- 只服务展示的辅助函数,通常适合跟着展示组件一起下沉。
- 父组件拆掉表格后,页面结构又清晰了一层。
- 模板长不一定最复杂,状态关系复杂才更值得谨慎处理。
- 当前任务页离真正干净的组合页又近了一步。