Vue 项目中封装 axios
在 Vue 项目中二次封装 axios,统一管理请求配置和拦截器
问题
在 Vue 项目中如何封装 axios,避免重复配置请求头、超时时间、错误处理等代码?
解答
为什么要封装
axios 的 API 很友好,可以直接使用。但随着项目规模增大,每次发起 HTTP 请求都要重复配置超时时间、请求头、环境地址、错误处理等,代码会变得冗余:
axios('http://localhost:3000/data', {
method: 'GET',
timeout: 1000,
withCredentials: true,
headers: {
'Content-Type': 'application/json',
Authorization: 'xxx',
},
transformRequest: [function (data, headers) {
return data;
}],
})
通过二次封装可以统一管理这些配置,提高代码质量和维护性。
封装步骤
1. 设置接口请求前缀
根据环境变量区分开发、测试、生产环境:
if (process.env.NODE_ENV === 'development') {
axios.defaults.baseURL = 'http://dev.xxx.com'
} else if (process.env.NODE_ENV === 'production') {
axios.defaults.baseURL = 'http://prod.xxx.com'
}
本地开发时在 vue.config.js 配置代理:
devServer: {
proxy: {
'/proxyApi': {
target: 'http://dev.xxx.com',
changeOrigin: true,
pathRewrite: {
'/proxyApi': ''
}
}
}
}
2. 设置请求头与超时时间
创建 axios 实例,配置通用请求头:
const service = axios.create({
timeout: 30000,
headers: {
get: {
'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8'
},
post: {
'Content-Type': 'application/json;charset=utf-8'
}
}
})
3. 封装请求方法
封装 GET 和 POST 方法:
// GET 请求
export function httpGet({ url, params = {} }) {
return new Promise((resolve, reject) => {
axios.get(url, { params })
.then((res) => {
resolve(res.data)
})
.catch(err => {
reject(err)
})
})
}
// POST 请求
export function httpPost({ url, data = {} }) {
return new Promise((resolve, reject) => {
axios.post(url, data)
.then((res) => {
resolve(res.data)
})
.catch(err => {
reject(err)
})
})
}
4. 统一管理 API
在 api.js 中统一管理接口:
import { httpGet, httpPost } from './http'
export const getorglist = (params = {}) => httpGet({
url: 'apps/api/org/list',
params
})
页面中调用:
import { getorglist } from '@/assets/js/api'
getorglist({ id: 200 }).then(res => {
console.log(res)
})
5. 请求拦截器
在请求发送前统一添加 token:
axios.interceptors.request.use(
config => {
const token = localStorage.getItem('token')
if (token) {
config.headers.Authorization = token
}
return config
},
error => {
return Promise.reject(error)
}
)
6. 响应拦截器
根据状态码统一处理响应:
axios.interceptors.response.use(
response => {
if (response.status === 200) {
if (response.data.code === 511) {
// 未授权处理
} else if (response.data.code === 510) {
// 未登录跳转登录页
} else {
return Promise.resolve(response)
}
}
return Promise.reject(response)
},
error => {
// 错误处理
return Promise.reject(error)
}
)
关键点
- 根据环境变量设置不同的 baseURL,开发环境配置代理解决跨域
- 创建 axios 实例统一配置超时时间和请求头
- 封装 GET、POST 等方法,返回 Promise 便于调用
- 使用请求拦截器统一添加 token 等认证信息
- 使用响应拦截器统一处理状态码、错误和登录态
目录