进入具体前端场景以后,我最不愿意用的一句验收结论是:
页面已经出来了,搜索、表格和分页也能用。
这句话只能证明主路径暂时走通,不能证明页面结构经得住下一次修改。
后台列表看起来很固定:上面放搜索条件,中间放el-table,下面接分页,旁边再塞新增、编辑和删除按钮。正因为结构太熟悉,Codex 很容易根据 Vue3 和 Element Plus 的通用知识,快速拼出一张“像后台列表”的页面。
问题是,它知道通用组件怎么写,却不知道当前项目怎样分配职责。
有的项目把搜索表单单独拆成组件,有的项目由页面统一持有查询状态;有的项目通过tabMixin管理列表和分页,有的项目使用组合式函数;有的接口直接接收查询字段,有的接口要求先做参数转换。
如果这些差异没有先确认,页面越完整,后面的返工范围反而越大。
所以,我审查 AI 生成的后台列表时,不会先纠结表格间距和按钮颜色,而是先查下面六个结构问题。
一、页面组件承担了多少职责
我先看页面文件里同时出现了什么:
搜索表单字段和校验;
列表、总数和分页状态;
请求参数转换;
列表接口与删除接口调用;
新增、编辑、查看弹框状态;
权限判断;
时间、状态等展示格式化;
大量局部样式。
这些内容全部写进一个.vue文件,不一定马上报错,却说明页面已经变成了多个职责的汇合点。
我不会机械地要求“一个区域一个组件”。拆分不是为了让文件数量好看,而是为了让变化边界清楚。我通常按下面三个问题判断:
搜索条件变化时,是否需要理解表格内部实现?
新增或编辑弹框变化时,是否会迫使列表页面一起修改?
另一张列表页能否复用分页、请求和删除流程?
如果答案频繁是“会”,说明职责边界还没有建立。
对当前可用的web-skills规范来说,常见范式是:搜索组件负责表单交互,页面负责组合区域,tabMixin统一列表、分页和删除流程,弹框由useDialogImp管理。这是当前规范中的项目约束,不是所有 Vue3 项目的唯一答案。
真正需要 Codex 做的,是识别目标项目采用了哪一种结构,而不是默认套用它最熟悉的写法。
二、同一份状态是否出现了多个“主人”
后台列表最容易复制的状态有三类:搜索条件、当前页和每页条数、列表加载状态。
例如,搜索组件里有一份form,父页面里又有一份queryParams,请求函数里再拼一份临时对象。三个对象字段相似,却没有明确谁是最终事实来源。
这时会出现很典型的现象:
输入框显示的是新条件,请求发出的还是旧条件;
点击重置以后表单清空了,分页查询仍带着上一次参数;
翻页时使用父页面保存的条件,再次查询时却使用子组件的新值;
修改每页条数后页码没有归一,得到空列表。
我会给每类状态明确一个负责人:
| 状态 | 需要确认的问题 |
|---|---|
| 搜索编辑态 | 用户正在输入但尚未查询的值由谁持有 |
| 已提交查询态 | 翻页和刷新时实际复用哪一份条件 |
| 分页态 | 当前页、每页条数和总数由谁统一修改 |
| 列表态 | 数据、空状态、错误状态和加载状态由谁维护 |
AI 经常把“能访问到状态”误当成“应该拥有状态”。我更关心的是:修改入口是否唯一,调用链是否看得懂。
三、界面字段和接口字段是否直接绑死
搜索表单里的字段,是为了方便用户编辑;接口参数,则要满足后端契约。两者经常不是同一种形状。
日期范围就是一个常见例子。界面组件可能需要:
form.createTime = ["2026-08-01 00:00:00", "2026-08-12 23:59:59"];
接口却可能要求:
{ startCreateTime: "2026-08-01 00:00:00", endCreateTime: "2026-08-12 23:59:59" }如果 Codex 直接把表单对象交给接口,短期看只是多传一个字段;长期会把界面状态、接口契约和重置逻辑绑在一起。
我会要求参数转换集中在明确的边界完成,并检查三件事:
临时界面字段是否会误传;
空字符串、空数组和
undefined是否符合接口约定;转换是否修改了原始表单对象。
当前web-skills中的时间范围处理和tabMixin参数组装,正是在处理这类边界。上面的字段只是结构示意,实际名称仍要以目标项目和接口契约为准。
四、获取列表是否存在多个请求入口
一张列表页至少会在这些时机请求数据:页面初始化、查询、重置、切换页码、修改每页条数,以及新增、编辑或删除成功之后。
如果每个事件都自己调用接口、自己拼参数,页面里很快就会出现多个“差不多”的请求入口。
我会追问:
无论从哪里触发,最后是否都进入同一个列表获取函数?
这个统一入口不一定叫getList,但它至少应该统一完成:
合并已提交查询条件与分页参数;
调用列表接口;
更新列表和总数;
处理加载结束;
输出可判断的成功或失败结果。
统一入口的意义不是少写几行代码,而是让查询规则、分页规则和异常处理只有一个落点。否则 AI 修正某个入口时,其他入口仍可能保留旧行为。
五、行操作有没有形成完整闭环
Codex 很容易把操作列写得很完整:查看、编辑、删除按钮一个不少。但“按钮能点击”只完成了入口,远没有形成闭环。
查看要确认是否只读、是否需要请求详情、关闭时是否产生无意义刷新。
编辑要确认传入的是行对象引用、浅拷贝,还是只传 ID 后重新获取详情;编辑过程中会不会直接污染表格当前行;保存成功后是否按既定规则刷新。
删除要确认是否有二次确认、权限是否沿用项目指令、删除当前页最后一条后怎样处理页码、接口失败时是否保留现有数据。
这些都不是 Element Plus 能替项目决定的业务规则。AI 可以按已知规则实现,但人必须先确认规则来自哪里。
六、有没有绕过项目已经存在的封装
这是我最常见、也最先阻止的一类结构问题。
项目已经有搜索按钮组件、分页组件、请求封装、权限指令和列表组合函数,AI 却又写了一套:
直接使用新的
ElPagination参数;自己创建 Axios 实例;
用普通布尔值重复实现全局 Loading;
用条件渲染替代已有权限指令;
手写删除确认,绕过统一消息组件。
单看局部,这些写法可能都成立;放回项目,它们会制造第二套规则。
我判断是否应该复用,不只看“项目里有没有同名组件”,还会看:
相邻列表页是否稳定使用它;
封装是否承担了隐藏契约,例如权限、加载状态和参数转换;
当前需求是否确实超出了封装能力;
绕过封装会不会让交互和错误处理不一致。
如果现有封装不适用,也不能让 Codex 悄悄绕过。它应该先说明差异、影响范围和替代方案,再由人决定是扩展封装还是局部例外。
我会先让 Codex 交一张结构检查表
在它继续补功能之前,我会要求先回答:
## 后台列表结构检查 1. 页面由哪些区域和组件组成? 2. 搜索态、已提交查询态、分页态和列表态分别由谁持有? 3. 表单字段在哪里转换为接口参数? 4. 初始化、查询、重置、翻页和操作成功是否共用请求入口? 5. 查看、编辑、删除各自怎样完成闭环? 6. 项目已有的列表、搜索、分页、弹框、请求和权限封装有哪些? 7. 当前方案有哪些地方没有沿用项目范式?为什么?
这张表不是为了让 AI 多解释,而是把结构问题提前暴露出来。
如果这些问题还说不清,我不会让它继续堆表格列。因为列配置改起来通常不难,状态归属和调用关系一旦写乱,后面每个需求都会放大返工。
写在最后
后台列表真正的复杂度,不在于会不会写el-table,而在于搜索、分页、接口、操作和项目封装能否组成一条稳定的数据流。
我先查六个结构问题,实际上是在确认三件事:谁负责、状态从哪里来、变化最终回到哪里。
下一篇我会继续往前一步:不让 Codex 凭通用经验猜列表结构,而是要求它从相邻页面、公共组件、组合函数和接口封装中,找出这个项目真正采用的列表页范式。
本系列持续更新,接下来会围绕 Vue3 与 Element Plus 后台列表,把前两周形成的 AI 协作闭环放进具体页面结构中验证。
参考资料
OpenAI Codex 用例:理解大型代码库,追踪请求流并定位相关模块