在 Vue 中对 axios 进行二次封装是项目开发中的常见实践,目的是统一管理请求、响应拦截、错误处理和全局配置。
核心目标
统一管理:集中处理请求配置、拦截器和错误逻辑。
简化调用:封装常用方法(GET/POST),避免重复代码。
增强功能:添加请求拦截(如 Token 注入)、响应拦截(如统一错误处理)。
实现步骤
1. 创建 Axios 实例
// utils/request.js
import axios from 'axios';
const service = axios.create({
baseURL: process.env.VUE_APP_BASE_API, // 从环境变量读取接口地址
timeout: 5000, // 请求超时时间
headers: { 'Content-Type': 'application/json' },
});2. 请求拦截器(Request Interceptor)
场景:添加 Token、设置请求头等。
service.interceptors.request.use(
(config) => {
const token = localStorage.getItem('token');
if (token) {
config.headers.Authorization = `Bearer ${token}`; // 注入 Token
}
return config;
},
(error) => Promise.reject(error)
);3. 响应拦截器(Response Interceptor)
场景:统一处理错误码、提取数据、全局错误提示。
service.interceptors.response.use(
(response) => response.data, // 直接返回数据部分
(error) => {
// 统一错误处理
if (error.response?.status === 401) {
// 未授权,跳转登录页
router.push('/login');
}
return Promise.reject(error); // 错误继续抛出
}
);4. 封装请求方法
封装
GET/POST等方法,简化调用:
const request = {
get(url, params) {
return service.get(url, { params });
},
post(url, data) {
return service.post(url, data);
},
// 可扩展 PUT/DELETE 等
};
export default request;5. 在组件中使用
import request from '@/utils/request';
export default {
methods: {
async fetchData() {
try {
const res = await request.get('/api/data');
console.log(res);
} catch (error) {
// 错误已由拦截器处理,此处可补充组件级逻辑
}
}
}
};关键设计点
环境变量:通过
process.env.VUE_APP_BASE_API区分开发/生产环境接口地址。错误处理:在拦截器中统一处理 HTTP 状态码(如 401/403/500)。
Token 管理:请求拦截器自动注入 Token,避免手动重复添加。
响应简化:直接返回
response.data,减少组件中的数据解构。
面试加分项
取消请求:使用
CancelToken避免重复请求(如页面切换时)。请求重试:对失败请求自动重试(如网络抖动)。
缓存策略:对 GET 请求添加缓存控制(如
axios-extensions)。TypeScript 支持:为封装方法添加类型定义。
如何处理跨域?(在开发环境中通过代理,生产环境配置nginx或后端设置CORS)
如何优化重复请求?(例如在请求拦截器中判断是否有相同的请求正在进行,如果有则取消之前的请求)
总结
二次封装的核心是通过拦截器统一处理请求/响应,封装方法简化调用,最终实现代码复用、可维护性和错误集中管理。面试时强调封装目的(避免重复代码、统一处理逻辑)和关键步骤(实例创建、拦截器、方法封装)即可。