Vben Admin 开发规范
本项目使用 Vben Admin 5.x (Ant Design Vue) + TypeScript + Vite 技术栈。
技术栈 技术 版本 用途 Vue 3.5.x UI 框架 TypeScript 5.x 类型系统 Ant Design Vue 4.x 组件库 Vite 7.x 构建工具 Pinia 3.x 状态管理 Vue Router 4.x 路由 Axios - HTTP 客户端 目录结构 frontend/apps/web-antd/src/ ├── api/ # API 接口 │ └── {module}/ │ └── index.ts ├── views/ # 页面视图 │ └── {module}/ │ ├── index.vue # 列表页 │ ├── detail.vue # 详情页 │ └── form.vue # 表单页 ├── components/ # 公共组件 ├── stores/ # 状态管理 │ └── {module}.ts ├── router/ # 路由配置 │ └── routes/ │ └── {module}.ts ├── hooks/ # 自定义 Hooks ├── utils/ # 工具函数 └── types/ # 类型定义 └── {module}.ts
代码模板 API 接口 // api/{module}/index.ts import { defHttp } from '@vben/request'; import type { {EntityName}, {EntityName}ListParams, {EntityName}FormData } from '@/types/{module}';
/* * {模块}API / enum Api { List = '/api/{module}', Detail = '/api/{module}/', Create = '/api/{module}', Update = '/api/{module}/', Delete = '/api/{module}/', }
/* * 获取{实体}列表 / export function get{EntityName}List(params: {EntityName}ListParams) { return defHttp.get<{EntityName}[]>({ url: Api.List, params, }); }
/*
* 获取{实体}详情
/
export function get{EntityName}Detail(id: number) {
return defHttp.get<{EntityName}>({
url: ${Api.Detail}${id},
});
}
/* * 创建{实体} / export function create{EntityName}(data: {EntityName}FormData) { return defHttp.post<{EntityName}>({ url: Api.Create, data, }); }
/*
* 更新{实体}
/
export function update{EntityName}(id: number, data: {EntityName}FormData) {
return defHttp.put<{EntityName}>({
url: ${Api.Update}${id},
data,
});
}
/*
* 删除{实体}
/
export function delete{EntityName}(id: number) {
return defHttp.delete({
url: ${Api.Delete}${id},
});
}
类型定义 // types/{module}.ts
/ * {实体}类型 */ export interface {EntityName} { / ID / id: number; / 名称 / name: string; / 创建时间 */ createdAt: string; / 更新时间 */ updatedAt: string; }
/ * {实体}列表查询参数 */ export interface {EntityName}ListParams { / 页码 / page?: number; / 每页数量 / size?: number; /* 关键词 / keyword?: string; }
/ * {实体}表单数据 */ export interface {EntityName}FormData { / 名称 */ name: string; }
列表页
<!-- 搜索区域 -->
<Card class="mb-4">
<Form :model="searchForm" layout="inline">
<FormItem label="关键词">
<Input v-model:value="searchForm.keyword" placeholder="请输入关键词" />
</FormItem>
<FormItem>
<Space>
<Button type="primary" @click="handleSearch">查询</Button>
<Button @click="handleReset">重置</Button>
</Space>
</FormItem>
</Form>
</Card>
<!-- 操作区域 -->
<Card>
<template #title>
<Button type="primary" @click="handleCreate">
<PlusOutlined /> 新增
</Button>
</template>
<!-- 表格 -->
<Table
:columns="columns"
:data-source="dataSource"
:loading="loading"
:pagination="pagination"
@change="handleTableChange"
>
<template #action="{ record }">
<Space>
<Button type="link" @click="handleEdit(record)">编辑</Button>
<Popconfirm title="确定删除吗?" @confirm="handleDelete(record.id)">
<Button type="link" danger>删除</Button>
</Popconfirm>
</Space>
</template>
</Table>
</Card>
表单页
<Card>
<Form
ref="formRef"
:model="formData"
:rules="rules"
:label-col="{ span: 4 }"
:wrapper-col="{ span: 12 }"
>
<FormItem label="名称" name="name">
<Input v-model:value="formData.name" placeholder="请输入名称" />
</FormItem>
<FormItem :wrapper-col="{ offset: 4, span: 12 }">
<Space>
<Button type="primary" :loading="submitting" @click="handleSubmit">
保存
</Button>
<Button @click="handleBack">取消</Button>
</Space>
</FormItem>
</Form>
</Card>
路由配置 // router/routes/{module}.ts import type { RouteRecordRaw } from 'vue-router';
/* * {模块}路由 / const routes: RouteRecordRaw[] = [ { path: '/{module}', name: '{EntityName}', meta: { title: '{模块名称}', icon: 'ant-design:appstore-outlined', }, children: [ { path: '', name: '{EntityName}List', component: () => import('@/views/{module}/index.vue'), meta: { title: '{模块}列表', }, }, { path: 'form/:id?', name: '{EntityName}Form', component: () => import('@/views/{module}/form.vue'), meta: { title: '{模块}表单', hideMenu: true, }, }, ], }, ];
export default routes;
命名规范 位置 规范 示例 文件夹 kebab-case user-management/ 组件文件 PascalCase.vue UserList.vue 工具文件 camelCase.ts formatDate.ts 类型文件 camelCase.ts user.ts 组件名 PascalCase UserList 变量名 camelCase userName 常量名 UPPER_SNAKE MAX_PAGE_SIZE 事件名 handle + 动作 handleSubmit 最佳实践 TypeScript: 所有文件使用 TypeScript,定义完整类型 组合式 API: 使用