Skip to content

适用场景

  • 跨项目/起新项目,输出可直接粘贴使用的 CRUD 骨架
  • 目标项目无专属通用组件,需要从零组装
  • 只希望生成页面代码,不想被项目约定束缚
  • 交付给团队其他人作为参考实现

不适用场景:

  • 仅修改样式或文案
  • 需求是非表格类业务(如纯图表、纯表单填报)

前置检查

  1. 确认目标项目基础技术栈:
    • 必须: Vue 3 + TypeScript + Element Plus
    • 可选: Vue Router(路由生成)、Pinia(store 生成)、Axios(请求层)
    • 可选: Tailwind CSS(样式策略:utility class 或 scoped CSS)
  2. 确认路径别名(如 @/#/./ 相对路径)
  3. 确认 HTTP 请求封装方式(项目封装的 request client 或裸 axios)
  4. 若无上述信息,按通用默认值生成,并在交付说明中列出需要替换的部分

输入契约

必须收集以下输入(缺一需先追问):

  • 模块英文名(kebab-case),如 user-management
  • 模块中文名,如 用户管理
  • 路由路径,如 /system/user
  • 功能边界:列表 / 查询 / 分页 / 新增 / 编辑 / 详情 / 删除 / 批量操作 / 导出
  • 字段清单(字段名、类型、是否必填、是否可搜索、是否列表显示、是否编辑显示)
  • 状态字段映射(枚举值 → 文案 → 颜色)
  • API 基础路径(如 /api/user
  • 是否生成 mock(true/false)
  • 路径别名(默认 @/
  • 请求工具(默认 import request from '@/utils/request'

推荐使用输入模板:references/input-template.md

输出产物

最小输出集合:

  • src/views/{kebab-name}/index.vue — 列表页(含查询/分页)
  • src/views/{kebab-name}/types.ts — 实体类型定义
  • src/api/{kebab-name}.ts — API 请求层

按需输出:

  • src/views/{kebab-name}/columns.ts — 表格列配置(若字段多于 5 列)
  • src/views/{kebab-name}/FormDialog.vue — 新增/编辑弹窗(若要求新增/编辑)
  • src/views/{kebab-name}/DetailDrawer.vue — 详情抽屉(若要求详情)
  • src/router/routes/modules/{kebab-name}.ts — 路由模块(若要求生成路由)
  • mock/{kebab-name}.ts — mock 数据(若要求 mock)

生成规范

类型文件 (types.ts)

typescript
// ── 实体类型 ──────────────────────────────────────────────
export interface {Entity} {
  id: number
  // ...字段
  createTime?: string
  updateTime?: string
}

// ── 列表查询参数 ──────────────────────────────────────────
export interface {Entity}ListParams {
  pageNum: number
  pageSize: number
  // ...可搜索字段(可选)
}

// ── 列表响应 ─────────────────────────────────────────────
export interface {Entity}ListResponse {
  list: {Entity}[]
  total: number
}

// ── 表单提交类型(新增/编辑共用或分开) ─────────────────────
export type {Entity}Form = Omit<{Entity}, 'id' | 'createTime' | 'updateTime'>
export type {Entity}CreateForm = {Entity}Form
export type {Entity}UpdateForm = {Entity}Form & { id: number }

API 文件 (api/{kebab-name}.ts)

typescript
import request from '@/utils/request'
import type { {Entity}, {Entity}ListParams, {Entity}ListResponse, {Entity}CreateForm, {Entity}UpdateForm } from '@/views/{kebab-name}/types'

// 查询列表(分页)
export function get{Entity}List(params: {Entity}ListParams) {
  return request.get<{Entity}ListResponse>('/api/{resource}', { params })
}

// 查询详情
export function get{Entity}Detail(id: number) {
  return request.get<{Entity}>(`/api/{resource}/${id}`)
}

// 新增
export function create{Entity}(data: {Entity}CreateForm) {
  return request.post<void>('/api/{resource}', data)
}

// 编辑
export function update{Entity}(data: {Entity}UpdateForm) {
  return request.put<void>(`/api/{resource}/${data.id}`, data)
}

// 删除
export function remove{Entity}(id: number) {
  return request.delete<void>(`/api/{resource}/${id}`)
}

// 批量删除(按需)
export function batchRemove{Entity}(ids: number[]) {
  return request.delete<void>('/api/{resource}/batch', { data: { ids } })
}

页面组件 (index.vue) 结构模式

<script setup lang="ts">
  ① 依赖导入(el-* 组件、类型、API)
  ② 响应式状态:loading/tableData/total/pageNum/pageSize/searchForm
  ③ 表格列定义(columns 数组或 columns.ts 引用)
  ④ 枚举映射(statusMap/statusLabel)
  ⑤ 数据加载函数 loadData()
  ⑥ 搜索/重置 handleSearch/handleReset
  ⑦ 新增/编辑 handleAdd/handleEdit
  ⑧ 删除 handleDelete(带 ElMessageBox 确认)
  ⑨ 分页变化监听 watch([pageNum, pageSize])
  ⑩ onMounted 调用 loadData()
</script>

<template>
  ① 页面容器(带标题区)
  ② 搜索表单(el-form inline + el-form-item + el-input/el-select)
  ③ 操作按钮区(新增/导出)
  ④ 数据表格(el-table + el-table-column)
  ⑤ 分页(el-pagination)
</template>

弹窗/抽屉组件规范

  • 弹窗使用 el-dialog,通过 defineProps<{ visible; row? }> + defineEmits<{ 'update:visible'; saved }> 控制
  • 表单使用 el-form ref + validate() 做提交前校验
  • 编辑时通过 watch(row) 回填表单数据,避免污染外部原始对象(使用 { ...row } 浅拷贝)

路由模块规范

typescript
import type { RouteRecordRaw } from 'vue-router'

const routes: RouteRecordRaw[] = [
  {
    path: '/{resource}',
    name: '{Entity}',
    meta: { title: '{中文名}', icon: 'xxx', requiresAuth: true },
    children: [
      {
        path: 'list',
        name: '{Entity}List',
        component: () => import('@/views/{kebab-name}/index.vue'),
        meta: { title: '{中文名}列表' },
      },
    ],
  },
]

export default routes

样式策略

  • 有 Tailwind CSS:用 utility class 写布局和间距,不写 scoped CSS
  • 无 Tailwind CSS:用 scoped CSS + BEM 命名,不写 inline style
  • 均不用:默认使用 scoped CSS
  • 颜色、字体、圆角等 token 优先用 CSS 变量,不硬编码十六进制

质量门槛

  • 不使用 any,不使用 as 强转绕过类型问题
  • 不硬编码 API 域名
  • 不省略 loading 状态(列表、提交按钮均需)
  • 删除操作必须有 ElMessageBox.confirm 二次确认
  • 编辑弹窗必须对原始行数据做浅拷贝,防止表单双向绑定污染外部状态
  • 所有用户可见文案使用 const/Map/对象集中定义,不散落在模板中

自检要求

生成完成后须在交付说明中明确:

  1. 是否通过 TypeScript 类型检查(如有 tsconfig 可告知执行命令验证)
  2. 需要替换的占位符(API 路径、请求工具导入路径)
  3. 需要手动配置的部分(路由注册、环境变量等)

交付说明格式

  1. 本次生成文件清单
  2. 功能覆盖清单
  3. 需要替换的占位符清单
  4. 跨项目适配说明(哪些需要按目标项目调整)
  5. 下一步建议(接真实接口、补权限控制、补国际化等)

参考

  • 输入模板:references/input-template.md
  • 验收清单:references/validation-checklist.md

Power By 数字海南