后端使用 AI 开发前端速成:第八期:对接真实后端接口
第八期:对接真实后端接口
本期目标:打通前后端联调全流程,处理真实世界的接口问题
核心理念:AI 生成代码用的是 mock 数据,对接真实接口是最容易出错的环节,需要仔细审查
目录
- 第一章:从 Swagger 文档生成 TypeScript 类型
- 第二章:接口联调基础
- 第三章:常见接口差异与适配
- 第四章:状态管理——loading / success / empty / error
- 第五章:实战——替换 mock 为真实接口
- 第六章:课后作业
第一章:从 Swagger 文档生成 TypeScript 类型
1.1 为什么从 Swagger 开始
Swagger 文档 = 接口契约 = 最好的 Prompt。给 AI 一个 Swagger 定义,它就知道:
- 接口地址和 HTTP 方法
- 请求参数和类型
- 响应数据结构
1.2 手动转换示例
Swagger 定义:
User:type:objectproperties:id:type:integerdescription:用户IDname:type:stringdescription:用户名email:type:stringformat:emailstatus:type:stringenum:[active,inactive]createdAt:type:stringformat:date-timeTypeScript 类型:
interfaceUser{id:numbername:stringemail:stringstatus:'active'|'inactive'createdAt:string}1.3 AI 辅助转换 Prompt
请将以下 Swagger JSON 定义转换为 TypeScript interface。 Swagger: [粘贴 Swagger JSON] 要求: - 使用 interface 而非 type - 可选字段标记 ? - 枚举值使用联合类型 - 日期字段使用 string 类型 - 生成对应的 API 请求/响应类型(使用泛型)第二章:接口联调基础
2.1 开发环境代理配置
Vite 代理(解决跨域):
// vite.config.tsexportdefaultdefineConfig({server:{proxy:{'/api':{target:'http://localhost:8080',// 后端地址changeOrigin:true,// rewrite: (path) => path.replace(/^\/api/, '') // 需要时去掉 /api 前缀}}}})环境变量:
// .env.developmentVITE_API_BASE_URL=/api// .env.productionVITE_API_BASE_URL=https://api.example.com// 代码中使用constbaseURL=import.meta.env.VITE_API_BASE_URL2.2 接口测试工具
| 工具 | 用途 | 推荐 |
|---|---|---|
| 浏览器 Network | 看请求/响应 | ⭐⭐⭐⭐⭐ |
| Postman / Apifox | 独立测试接口 | ⭐⭐⭐⭐ |
| Swagger UI | 在线测试 | ⭐⭐⭐⭐ |
| Console.log | 快速调试 | ⭐⭐⭐ |
第三章:常见接口差异与适配
3.1 常见问题清单
| 问题 | 现象 | 解决方案 |
|---|---|---|
| 字段名不一致 | 前端用page,后端用pageNum | 封装转换层 |
| 嵌套结构不同 | 前端期望data.list,后端返回data.records | 响应拦截器适配 |
| 枚举值格式 | 前端用'active',后端用1 | 映射转换 |
| 分页参数不统一 | 有的接口pageNo,有的pageNum | 统一封装 |
| 日期格式 | 前端期望YYYY-MM-DD,后端返回时间戳 | 工具函数转换 |
| 错误码不一致 | 有的code: 200,有的code: 0 | 响应拦截器统一 |
3.2 适配层封装
// utils/adapter.ts// 统一处理前后端字段差异exportfunctionadaptUser(user:BackendUser):User{return{id:user.id,name:user.name,email:user.email,status:user.state===1?'active':'inactive',createdAt:formatDate(user.createTime)}}exportfunctionadaptPagination(params:PaginationParams):BackendPagination{return{pageNum:params.page,pageSize:params.pageSize}}3.3 响应拦截器适配
// 在 Axios 响应拦截器中统一适配request.interceptors.response.use((response)=>{const{code,data,message}=response.data// 统一错误码if(code!==200&&code!==0){returnPromise.reject(newError(message))}// 适配分页数据结构if(data?.records){return{list:data.records,total:data.total}}returndata})第四章:状态管理——loading / success / empty / error
4.1 四种状态
初始状态 → loading(请求中) ↓ ┌──────┴──────┐ success error (有数据) (报错) ↓ empty(无数据)4.2 完整的状态处理
<script setup> import { ref } from 'vue' const loading = ref(false) const tableData = ref([]) const error = ref(null) const fetchData = async () => { loading.value = true error.value = null try { const data = await request.get('/api/users') tableData.value = data.list || [] } catch (err) { error.value = err.message || '获取数据失败' tableData.value = [] } finally { loading.value = false } } </script> <template> <div> <!-- 加载中 --> <div v-if="loading" class="loading"> 加载中... </div> <!-- 错误 --> <div v-else-if="error" class="error"> <p>{{ error }}</p> <el-button @click="fetchData">重试</el-button> </div> <!-- 空数据 --> <div v-else-if="tableData.length === 0" class="empty"> <el-empty description="暂无数据" /> </div> <!-- 有数据 --> <el-table v-else :data="tableData"> ... </el-table> </div> </template>4.3 更优雅的状态封装(Hook)
// composables/useAsync.tsimport{ref}from'vue'interfaceAsyncState<T>{data:T|nullloading:booleanerror:string|null}exportfunctionuseAsync<T>(asyncFn:()=>Promise<T>){conststate=ref<AsyncState<T>>({data:null,loading:false,error:null})constexecute=async()=>{state.value.loading=truestate.value.error=nulltry{state.value.data=awaitasyncFn()}catch(err:any){state.value.error=err.message state.value.data=null}finally{state.value.loading=false}}return{state,execute}}// 使用const{state,execute}=useAsync(()=>request.get('/api/users'))onMounted(execute)第五章:实战——替换 mock 为真实接口
5.1 步骤清单
- 获取 Swagger 文档→ 让 AI 生成 TypeScript 类型
- 配置代理→ vite.config.ts 或 nginx
- 检查字段差异→ 对比 mock 和真实接口
- 修改请求代码→ 替换 mock 地址
- 处理响应适配→ 字段名、结构差异
- 测试所有场景→ loading、空数据、错误
5.2 给 AI 的 Prompt
请帮我把以下 mock 数据代码改成对接真实接口。 当前代码: [粘贴代码] 接口信息: - 地址:GET /api/users - 参数:{ pageNum, pageSize, keyword?, status? } - 返回:{ code, data: { records: User[], total }, message } 已知差异: 1. 后端用 pageNum,前端用 page → 需要转换 2. 后端返回 records,前端期望 list → 需要适配 3. 后端状态用 1/0,前端用 'active'/'inactive' → 需要映射 要求: - 使用已有的 request 封装 - 处理 loading、error、empty 状态 - 接口报错时给用户友好提示 - 严格 TypeScript第六章:实战
6.1 必做实战
实战 1:对接真实接口
找一个你工作中的后端接口(或模拟一个),完成以下步骤:
- 根据 Swagger 生成 TypeScript 类型
- 配置 Vite 代理
- 替换 mock 为真实请求
- 处理字段差异
- 测试 loading/success/empty/error 四种状态
实战 2:封装 useAsync Hook
实现一个通用的useAsyncHook,封装异步请求的状态管理:
- data / loading / error 状态
- 支持重试
- 支持手动执行
下一期预告:调试排错与性能优化 —— DevTools 使用、常见问题定位、性能优化技巧
