--- name: v3-create-crud description: 创建增删改查(CRUD)页面,基于 Element Plus 组件库,包含表格、搜索、分页、新增/编辑弹窗、删除确认等功能。当用户提到以下任何场景时都应触发:创建管理页面、创建列表页、创建表格页。即使用户没有明确说 CRUD,只要意图是创建带表格和表单操作的后台页面就应该使用此 Skill。使用时需提供模块名称和字段信息。 metadata: author: Glittering Ma & pany version: "2026.06.13" --- # 创建 CRUD 页面 根据用户提供的模块名称和字段信息,生成增删改查页面。 本 Skill 定义的是默认 CRUD 模式,当用户的实际需求与本 Skill 约定冲突时,以用户需求为准,灵活调整。 ## 输入要求 用户需提供: 1. **模块名称**(如 `product`、`order`)— 用于目录名和命名 2. **字段列表** — 每个字段需明确: - 字段名(英文,camelCase) - 中文标签 - 类型(string / number / boolean / enum / date 等) - 是否必填 - 是否作为搜索条件 - 是否需要自定义渲染(如 tag 状态展示) 如果用户信息不完整,主动询问补全后再生成。 ## 生成文件 在 `src/pages/<模块路径>/` 下生成: 1. `index.vue` — 页面主文件 2. `apis/index.ts` — 接口文件 3. `apis/type.ts` — 类型定义 ## 设计决策指引 生成代码时需要做出的判断(不要机械套用,根据具体场景决定): **弹窗宽度** — 默认用 `30%`,有复杂布局用 `50%` 或更大的比例。 **工具栏按钮** — 按需组合,不必全部包含: - "新增" 几乎总是需要的 - "批量删除" 仅在有批量操作需求时添加(对应表格 selection 列) - "下载/导出" 仅在有导出需求时添加 - "刷新当前页" 推荐保留,方便调试和手动刷新 **删除确认文案** — 选择对用户最有辨识度的字段作为确认提示(如用户名、订单编号、商品名称),而不是 id。 **搜索参数传递** — 保持简单,避免类型体操: - 字段少(2-3 个)时可以逐个列出 - 字段多时用 `...searchData` 展开更简洁 - 核心原则:不要出现 `as any`,除非明确要求 **表单字段 vs 表格列** — 不是所有字段都同时出现在两处: - 仅创建时需要的字段(如密码):表单中有,表格中无 - 系统生成的字段(如创建时间):表格中有,表单中无 - 用 `v-if="formData.id === undefined"` 控制仅新增时显示的字段 ## 页面结构规范 页面整体包裹在 `
` 中,由搜索区域、表格区域、弹窗三部分组成。 ### 1. 搜索区域 - `el-card`:`v-loading="loading"` + `shadow="never"` + `class="search-wrapper"` - 内含 `el-form`:`ref="searchFormRef"` + `:inline="true"` + `:model="searchData"` - 每个搜索字段设置 `prop`(`resetFields` 依赖它)和 `label` - 末尾放查询按钮(`:icon="Search"` + `type="primary"`)和重置按钮(`:icon="Refresh"`) ### 2. 表格区域 - `el-card`:`v-loading="loading"` + `shadow="never"` - 工具栏(`div.toolbar-wrapper`)分左右两侧: - 左侧:文字按钮(新增、批量删除等) - 右侧:圆形图标按钮 + `el-tooltip`(下载、刷新当前页等) - 表格(`div.table-wrapper` > `el-table :data="tableData"`): - 需要批量操作时加 `type="selection"` 首列 - 数据列:`prop` + `label` + `align="center"` - 操作列:`fixed="right"` + 适当 `width` + `align="center"`,内含修改/删除按钮(`text bg size="small"`) - 操作列按钮将 `scope.row` 传给强类型 handler 时,使用 `scope.row as XxxData` 明确行类型,避免 Element Plus 默认 `DefaultRow` 导致 `vue-tsc` 报错,不要使用 `as any` - 分页(`div.pager-wrapper` > `el-pagination`) ### 3. 弹窗 - `el-dialog`:`v-model="dialogVisible"` + 通过 `formData.id === undefined` 判断新增/修改标题 + `@closed="resetForm"` - 使用 `@closed` 而非 `@close`(确保关闭动画结束后再重置,避免用户看到表单内容闪烁) - 表单:`ref="formRef"` + `:model="formData"` + `:rules="formRules"` + `label-width="auto"` - footer:取消按钮 + 确认按钮(`type="primary"` + `:loading="loading"`) ## 代码组织规范 使用 `