# Vben Admin 5.x — 标准模板(可直接复制再改) 占位符 **`YourItem`**、**`YourDto`** 等请替换为真实类型。**新增/编辑**支持 **Modal** 与 **Drawer** 两种承载(与 `system/dept`、`system/menu` 一致):**同一功能只选一种**,列表与子组件 `form.vue` 必须使用同一套(`useVbenModal`↔`Modal` 或 `useVbenDrawer`↔`Drawer`)。`web-ele` 用 Element Plus,`playground` 用 Ant Design Vue,**勿混用**。 --- ## 1. `config.ts`(查询 + 列 + 组装 gridOptions) ```ts import type { VbenFormSchema } from '#/adapter/form'; import type { OnActionClickFn, VxeTableGridColumns, VxeTableGridOptions, } from '#/adapter/vxe-table'; import type { YourItem } from '#/api/your-module'; import { yourPageListApi } from '#/api/your-module'; export const YOUR_TABLE_TITLE_KEY = 'page.yourModule.list'; export const listFormOptions = { collapsed: false, schema: [ { component: 'Input', componentProps: { clearable: true, placeholder: '关键词' }, fieldName: 'keyword', label: '关键词', }, ] as VbenFormSchema[], showCollapseButton: false, submitOnChange: true, wrapperClass: 'grid-cols-1 md:grid-cols-4', }; export function buildColumns( onActionClick: OnActionClickFn, ): VxeTableGridColumns { return [ { type: 'seq', title: '序号', width: 56, fixed: 'left' }, { field: 'Id', title: 'Id', minWidth: 80 }, { align: 'center', cellRender: { attrs: { nameField: 'Name', onClick: onActionClick, }, name: 'CellOperation', }, field: 'operation', fixed: 'right', title: '操作', width: 160, }, ]; } export function buildGridOptions( onRowAction: OnActionClickFn, ): VxeTableGridOptions { return { columns: buildColumns(onRowAction), height: 'auto', keepSource: true, pagerConfig: {}, proxyConfig: { ajax: { query: async ({ page }, formValues) => { const res = await yourPageListApi({ page: page?.currentPage, pageSize: page?.pageSize, ...formValues, }); return res; }, }, }, toolbarConfig: { custom: true, export: false, refresh: true, zoom: true, }, }; } ``` **说明**:`proxyConfig.ajax.query` 的入参/返回值必须与项目现有 API 一致。 --- ## 2a. `index.vue` — **Modal**(`useVbenModal`) 与 `system/dept/list.vue` 同类。 ```vue ``` --- ## 2b. `index.vue` — **Drawer**(`useVbenDrawer`) 与 `system/menu/list.vue` / `system/role/list.vue` 同类;仅将 **`useVbenModal` → `useVbenDrawer`**,**`FormModal` → `FormDrawer`**,**`formModalApi` → `formDrawerApi`**。 ```vue ``` **说明**:`playground` 可将 `ElButton` 换成 Ant Design Vue 的 `Button`。 --- ## 3a. `modules/form.vue` — **Modal**(`useVbenModal` + ``) 与 `system/dept/modules/form.vue` 同类。 **`data.ts` 中导出 schema:** ```ts import type { VbenFormSchema } from '#/adapter/form'; export function useYourFormSchema(): VbenFormSchema[] { return [ { component: 'Input', fieldName: 'name', label: '名称', rules: 'required', }, ]; } ``` **建议(类似 `carGps/config.ts`):把表单 schema/默认值外置到 `config.ts` / `data.ts`,`modules/form.vue` 只负责流程。** ```vue ``` **`web-ele`**:将 `Button` 改为 `ElButton`(`from 'element-plus'`);**`modalApi.unlock()` 与 `modalApi.lock(false)` 等价**,与邻近文件择一即可。 --- ## 3b. `modules/form.vue` — **Drawer**(`useVbenDrawer` + ``) 与 `system/menu/modules/form.vue` 同类:子组件内 **`useVbenDrawer`**,**`drawerApi.getData` / `drawerApi.lock` / `drawerApi.unlock`**。 ```vue ``` **说明**:复杂表单可在 `Drawer` 上增加 `class` 控制宽度(如 `max-w-200`);`onOpenChange` 内数据清洗逻辑按 **`menu/modules/form.vue`** 等业务文件对齐。 --- ## 4. 模板使用顺序 1. 选定 **Modal 或 Drawer**(§6 对照表 + 仓库内同类页)。 2. 复制 **`config.ts`**。 3. 复制 **`data.ts`** 中的 **`useYourFormSchema`**。 4. 复制 **`modules/form.vue`**:**§3a** 或 **§3b**(须与列表 **§2a** 或 **§2b** 一致)。 5. 复制 **`index.vue`**:**§2a** 或 **§2b**。