# 3.9 前端联调指引 :::tip 概述 后端接口开发完成后,需要在前端创建对应的 API 模块和页面组件。本节以 example 模块为例,提供简要指引,详细内容参考 [第 9 章](/zh/frontend/overview.html)。 ::: ## 联调流程 ```text 1. 创建 API 模块 → ui/src/api/tool/example.ts 2. 创建页面组件 → ui/src/views/tool/example/index.vue 3. 配置菜单组件路径 → 后端菜单管理中设置 component 4. 测试联调 ``` ## 步骤一:创建 API 模块 在 `ui/src/api/tool/` 下创建 `example.ts`: ```typescript // ui/src/api/tool/example.ts import { http } from '@/utils/http/axios'; /** * 案例演示模块接口 * * 提供案例演示的增删改查及导入导出接口调用。 */ /** * 获取案例演示分页列表 * * @param params 查询参数,包含 pageNo、pageSize 及业务筛选条件 * @returns 分页结果,含 records、total、current、size */ export function getExamplePage(params?: Record) { return http.request({ url: '/example/page', method: 'GET', params, }); } /** * 获取全部案例演示列表 */ export function getExampleList(params?: Record) { return http.request({ url: '/example/list', method: 'GET', params, }); } /** * 根据 ID 获取案例演示详情 */ export function getExampleDetail(id: number) { return http.request({ url: '/example/detail/' + id, method: 'get', }); } /** * 添加案例演示(入参 camelCase,后端 FormRequest 自动转换) */ export function exampleAdd(data: any) { return http.request({ url: '/example/add', method: 'POST', data, }); } /** * 更新案例演示(需包含主键 id) */ export function exampleUpdate(data: any) { return http.request({ url: '/example/update', method: 'PUT', data, }); } /** * 删除案例演示 */ export function exampleDelete(id: number) { return http.request({ url: '/example/delete/' + id, method: 'DELETE', }); } /** * 批量删除案例演示(形如 { ids: [1, 2, 3] }) * * 注意:批量删除后端路由为 DELETE(请求体仍传 ids 数组)。 */ export function exampleBatchDelete(data: any) { return http.request({ url: '/example/batchDelete', method: 'DELETE', data, }); } /** * 导入案例演示(FormData 文件) */ export function exampleImport(data: any) { return http.request({ url: '/example/import', method: 'POST', data, }); } /** * 导出案例演示(返回文件 URL) */ export function exampleExport(params?: Record) { return http.request({ url: '/example/export', method: 'GET', params, }); } ``` :::tip HTTP 封装(Token 携带、401 处理、统一错误提示、camel/snake 转换)由 `http` 实例统一完成,API 模块只描述"哪个地址、什么方法"。见 [9.4 HTTP 请求封装](/zh/frontend/http.html)。 ::: ## 步骤二:创建页面组件 在 `ui/src/views/tool/example/` 下创建以下 5 个文件(与代码生成器输出结构一致): | 文件 | 说明 | |------|------| | `index.vue` | 列表页(表格 + 搜索 + 分页) | | `edit.vue` | 新增/编辑弹窗表单 | | `detail.vue` | 详情查看页 | | `columns.ts` | 表格列定义 | | `querySchemas.ts` | 搜索表单字段定义 | :::tip 关于以下示例 以下代码使用原生 `el-table` / `el-form` 简化展示核心逻辑。实际项目中应使用封装好的 `BasicTable` + `useForm` 等组合式组件,详见 [第 9 章组件文档](/zh/frontend/overview.html)。 ::: `index.vue`(列表页)示例: ```vue ``` ## 步骤三:配置菜单 在后端菜单管理中,将组件路径设置为: ```text tool/example/index ``` 前端路由系统会自动将此路径映射到 `ui/src/views/tool/example/index.vue`(动态路由由后端菜单数据驱动)。 ## 步骤四:测试联调 1. 确保后端服务运行:`php artisan serve`(或 `composer dev`) 2. 确保前端服务运行:`cd ui && pnpm dev`(开发端口 8001) 3. 为测试角色分配新菜单权限(见 [3.8 权限节点配置](/zh/guide/permission.html)) 4. 刷新前端页面,侧边栏应出现"案例演示"菜单 5. 点击菜单,测试增删改查功能 ### 联调自查顺序 ```text 接口 404 → 路由未注册 / URL、HTTP 方法与 routes/api.php 不一致 接口 401 → Token 未携带或过期(看 http 封装是否注入 Authorization) 接口 403 → 权限码未配置 / 角色未分配(见 3.8) 接口 code=1 → 看 msg 与 data(FormRequest 字段错误明细) 表格不显示 → 响应结构应为 data.records / data.total,检查绑定字段 菜单不显示 → 组件路径错误 / 角色未分配菜单 / 前端 views 下无对应 .vue ``` 详细前端开发内容请参考 [第 9 章](/zh/frontend/overview.html)。