1. 引言
在 Vue 3 项目中,封装请求模块是提高代码复用性和可维护性的重要步骤。通过封装 Axios,我们可以统一处理请求头、Token、错误处理和数据加密等逻辑,从而避免重复代码并提升开发效率。
2. 封装 Axios 请求模块
以下是一个完整的 Axios 请求封装示例,适用于 Vue 3 项目:
request.ts:
import axios from 'axios'
import { CURRENT_CONFIG } from './config'
import { message } from 'ant-design-vue'
import router from '/@/router'
import { ELocalStorageKey, ERouterName, EUserType } from '/@/types/enums'
import Cookies from 'js-cookie'
export * from './type'
const REQUEST_ID = 'X-Request-Id'
function getAuthToken () {
return Cookies.get(ELocalStorageKey.Token) || new Date().getTime()
}
const instance = axios.create({
headers: {
'Content-Type': 'application/json',
},
})
instance.interceptors.request.use(
config => {
config.headers[ELocalStorageKey.Token] = getAuthToken()
config.baseURL = CURRENT_CONFIG.baseURL
return config
},
error => {
return Promise.reject(error)
},
)
instance.interceptors.response.use(
response => {
if (response.data.code && response.data.code !== 0) {
if (response.data.message == '请重新登录') {
setTimeout(() => {
router.push(ERouterName.PROJECT)
return
}, 1000);
}
}
return response
},
err => {
const requestId = err?.config?.headers && err?.config?.headers[REQUEST_ID]
if (requestId) {
console.info(REQUEST_ID, ':', requestId)
}
let description = '-'
if (err.response?.data && err.response.data.message) {
description = err.response.data.message
}
if (err.response?.data && err.response.data.result) {
description = err.response.data.result.message
}
if (!err.response || !err.response.status) {
message.error('网络异常,请检查服务,然后重试')
return
}
if (err.response?.status !== 200) {
message.error(`ERROR_CODE: ${err.response?.status}`)
}
if (err.response?.status === 401) {
console.error(err.response)
Cookies.remove(ELocalStorageKey.Token);
Cookies.remove(ELocalStorageKey.Username);
router.push(ERouterName.PROJECT)
}
return Promise.reject(err)
},
)
export default instance
3. 封装的关键点
-
统一配置:通过 Axios 实例设置
baseURL
和超时时间。 -
Token 管理:在请求拦截器中动态添加 Token。
-
错误处理:在响应拦截器中统一处理错误,避免在组件中重复编写错误处理逻辑。
-
请求 ID:为每个请求添加唯一 ID,便于调试。
-
跳转逻辑:根据错误类型(如 401)清除 Token 并跳转到登录页面。
4. 使用封装的请求模块
yourFile.ts:
import request, { IWorkspaceResponse } from '/@/api/http/request'
//GET
export const getYourInterface = async (body: elementGroupsReq): Promise<IWorkspaceResponse<any>> => {
const url = `${PREFIX}/yourInterfaceUrl/`+ your_id + '/element-groups'
const result = await request.get(url, body)
return result.data
}
//POST
export const postYourInterface = async (pid: string, body: PostElementsBody): Promise<IWorkspaceResponse<{ id: string }>> => {
const url = `${PREFIX}/InterfaceUrl/` + your_id + `/element-groups/${pid}/elements`
const result = await request.post(url, body)
return result.data
}
vue文件:
import {postYourInterface ,getYourInterface } from '/@/api/layer'
async function getYourInterfaceData (type?: string) {
const result = await getYourInterface ({
yourId: '',
isDistributed: true
})
mapLayers.value = result.data
}
async function postYourInterfaceData(obj) {
const req = await postYourInterface (参数,参数)
mapLayers.value = req.data
}
5. 注意事项
-
跨域问题:如果遇到跨域问题,可以在后端配置 CORS 或通过代理解决。
-
Token 刷新机制:如果需要支持 Token 刷新,可以在响应拦截器中捕获 401 状态码并自动刷新 Token。
-
环境变量:使用
import.meta.env
动态配置 API 地址。
6. 总结
通过封装 Axios,我们实现了一个高效、灵活且易于维护的请求模块。它不仅减少了重复代码,还提升了项目的整体质量。希望本文的示例能帮助你在 Vue 3 项目中更好地管理 HTTP 请求。
如果你有任何问题或建议,欢迎留言交流!