这一期,我们继续深入网络请求封装的优化实践。上一期我们探讨了前端点选验证码组件的实现,本期则将重点放在请求层的细节打磨与优化上。

网络请求封装优化
首先来看第一个改动:将自定义请求选项从嵌套参数中分离出来,独立传递。
请求选项独立参数传递:提升代码可读性
目前,当需要自定义请求选项时,代码写法如下——在第一个参数中嵌套一个requestOptions对象:
复制代码export function checkClickCaptcha(data: ClickRequest, apiBaseURL?: string) {
return request({
url: '/common/captcha/verify',
method: 'POST',
requestOptions: {
loading: true,
cancelDuplicate: true,
showErrorMessage: false,
},
})
}
直观来看,我们希望改为如下形式:将requestOptions直接作为第二个参数独立传递给request函数。这样,第一个参数仅包含axios的标准请求配置,第二个参数则为自定义选项:
复制代码export function checkClickCaptcha(data: ClickRequest) {
return request(
{
url: '/common/captcha/verify',
method: 'POST',
data,
},
{
loading: true,
cancelDuplicate: true,
showErrorMessage: false,
}
)
}
参数1为axios请求配置,参数2为自定义请求选项。独立分离后,代码的可读性、类型推导、扩展性及维护性均得到全面提升。这个思路源于编写提示词时的灵感,直接交给CC(AI助手)实现:
复制代码● 重构完成。改动总结如下:修改的文件1. src/utils/request.ts- 删除了 RequestConfig 接口(已不需要,直接使用 AxiosRequestConfig)
- request 函数签名从 request(config: RequestConfig) 改为 request(config: AxiosRequestConfig, options?: RequestOptions)
- 内部将 options 合并到 config 的 requestOptions 字段上,拦截器逻辑无需任何改动2. src/api/common.ts- checkClickCaptcha 中的 requestOptions 从第一个参数嵌套中提取为独立的第二个参数:
// 之前
request({ url: '...', requestOptions: { showErrorMessage: false } })
// 之后
request({ url: '...' }, { showErrorMessage: false })无需改动的文件- src/api/admin/index.ts — 未使用 requestOptions,现有的单参数调用完全兼容
- 其他不涉及 requestOptions 的调用方同样无需改动,因为 AxiosRequestConfig 就是之前第一个参数去掉 requestOptions 后的类型 Baked for 50s
人工review后确认无误。说实话,实际修改的代码量并不多,反而提示词写了不少。不得不承认,有些失算。
后端接口响应字段自动转换为 camelCase 命名风格
第二个改动更具趣味性。各语言服务端及网络传输惯例中,JSON字段通常采用snake_case命名。而前端开发者更习惯使用camelCase访问数据。因此,在请求层实现自动转换,已是常见最佳实践。
这里要求CC添加一个转换开关,默认开启,并实现该功能。来看具体效果:
全部完成,以下是变更总结:
变更清单
src/utils/request.ts — 核心改造
| 变更项 | 说明描述 |
|---|---|
| import { camelCase } | 引入 lodash-es 的 camelCase,复用已有依赖,无需新增 |
| convertCase?: boolean | 新增请求选项 convertCase,默认开启(true) |
| keysToCamelCase() | 递归转换函数,支持对象、数组及嵌套结构 |
| 响应拦截器 L190-193 | 在响应拦截器中自动对 response.data.data 执行转换 |
接口 + Store + 模板统一改名
| 文件 | 变更 |
|---|---|
| src/stores/interface/index.ts | 字段命名从 snake_case 改为 camelCase:last_login_at → lastLoginAt,last_login_ip → lastLoginIp |
| src/stores/adminInfo.ts | 初始 state 同步改为 camelCase |
| src/layouts/admin/components/na vMenu.vue | 模板变量引用改为 adminInfo.lastLoginAt |
使用方式:
// 默认:自动转换(开关打开)
request({ url: '/admin/init', method: 'GET' })
// 某个接口不需要转换时,显式关闭
request({ url: '/some/api', method: 'GET' }, { convertCase: false })
这样一来,前端所有接口的响应字段均统一为camelCase风格,彻底解决了命名不一致的问题。
在review时,直接要求它同时将请求中的camelCase数据反向转换为snake_case(由同一开关控制)。从此前后端命名风格彻底解耦——该功能通常仅在大型项目中配置,但借助AI轻松实现,效果显著。
现在起:
API响应中,snake_case命名字段自动转换为camelCase;- 发起请求时,传递的
camelCase数据(含data和params)自动转为snake_case。
前端可全程使用camelCase,开发体验显著提升。例如:
- 访问响应数据时,接口返回
res.data.data.admin_info.last_login_at,现在可直接用res.data.data.adminInfo.lastLoginAt获取; - 发起请求时,
data可写为{adminInfo: {lastLoginAt: '2023-05-01'}},发送时自动转换为{admin_info: {last_login_at: '2023-05-01'}},简洁高效。
本期网络请求封装优化就此告一段落。下期将继续推进后续模块的封装与优化工作,敬请期待。
