🌟 开篇:为什么需要封装Axios?
在Web开发中,网络请求就像应用程序的血管系统🌐。直接使用原生Axios可能会面临:
🔸 重复代码 - 每个请求都要写完整URL
🔸 脆弱性 - 缺乏统一错误处理机制
🔸 可维护性差 - 基础配置散落各处
通过封装Axios实例,我们可以实现统一管理、快速迭代、优雅交互!
🛠️ 一、基础封装 | 创建你的请求管家
代码解析(核心骨架):
import axios from 'axios'
// 🏭 创建axios实例工厂
const request = axios.create({
baseURL: '/api', // 🌐 API基础路径(解决跨域关键配置)
timeout: 600000, // ⏳ 超时时间(单位:毫秒,按需调整)
})
// 🔄 响应拦截器 - 统一处理返回数据
request.interceptors.response.use(
(response) => {
return response.data // 🎯 直接返回核心数据
},
(error) => {
return Promise.reject(error) // 🚨 传递错误
}
)
export default request
配置亮点解析:
-
baseURL:
- 开发环境配合代理解决跨域(vue.config.js示例):
devServer: { proxy: { '/api': { target: 'http://real-api.com', changeOrigin: true, pathRewrite: { '^/api': '' } } } }
-
timeout:
- 根据业务场景灵活设置(大文件上传可适当延长)
- 推荐预设阶梯值:
timeout: process.env.NODE_ENV === 'development' ? 30000 : 10000
🔥 二、实战增强 | 给拦截器装上智能大脑
1. 全局Loading状态管理
let loadingInstance = null
// ➕ 添加请求拦截器
request.interceptors.request.use(config => {
loadingInstance = ElLoading.service({ fullscreen: true })
return config
})
// ➖ 响应拦截器增强
request.interceptors.response.use(
response => {
loadingInstance?.close()
return response.data
},
error => {
loadingInstance?.close()
ElMessage.error(error.message)
return Promise.reject(error)
}
)
2. 智能错误处理
const errorHandler = (error) => {
const status = error.response?.status
const errorMap = {
400: '请求参数错误',
401: '登录状态过期',
403: '没有操作权限',
404: '资源不存在',
500: '服务器开小差了~'
}
ElMessage.error(errorMap[status] || '网络异常')
return Promise.reject(error)
}
// 在响应拦截器中使用
request.interceptors.response.use(
response => response.data,
errorHandler // 🎯 替换原有错误处理
)
⚡ 三、高级扩展 | 打造全能请求工具
1. 支持TypeScript类型
// types/request.d.ts
declare module '@vue/runtime-core' {
interface ComponentCustomProperties {
$http: typeof request
}
}
2. 多实例管理
// 创建不同业务的独立实例
const adminRequest = axios.create({
baseURL: '/admin-api',
timeout: 30000
})
const publicRequest = axios.create({
baseURL: '/public-api',
timeout: 15000
})
3. 请求取消功能
const cancelTokenSources = new Map()
const addCancelToken = (config) => {
const source = axios.CancelToken.source()
config.cancelToken = source.token
cancelTokenSources.set(config.url, source)
return config
}
// 在请求拦截器中调用
request.interceptors.request.use(config => {
return addCancelToken(config)
})
// 提供取消方法
export const cancelRequest = (url) => {
if (cancelTokenSources.has(url)) {
cancelTokenSources.get(url).cancel()
cancelTokenSources.delete(url)
}
}
🚨 四、最佳实践 | 避坑指南
-
路径匹配陷阱
// ❌ 错误写法(可能造成代理失效) baseURL: 'http://localhost:8080/api' // ✅ 正确写法(配合代理使用相对路径) baseURL: '/api'
-
敏感信息处理
// 在请求拦截器中过滤敏感数据 request.interceptors.request.use(config => { if (config.data?.password) { config.data.password = '******' } return config })
-
性能优化技巧
// 接口缓存方案 const cache = new Map() request.interceptors.request.use(config => { if (config.cache) { const cacheData = cache.get(config.url) if (cacheData) return Promise.resolve(cacheData) } return config })
📚 五、生态整合 | 扩展方案
-
Mock数据集成
if (process.env.VUE_APP_MOCK === 'true') { import('./mock').then(module => { module.setupMock(request) }) }
-
配合Vuex管理状态
// store/modules/request.js export default { state: { pendingRequests: 0 }, mutations: { INCREMENT_PENDING(state) { state.pendingRequests++ }, DECREMENT_PENDING(state) { state.pendingRequests-- } } }
🎯 六、总结与源码
通过本文的封装方案,你可以获得:
✅ 统一配置管理
✅ 全局状态可视化
✅ 可扩展的拦截器系统
✅ 企业级错误处理能力
最终版源码地址:GitHub示例仓库
💡 讨论互动
你在封装Axios时有哪些独创技巧?遇到过哪些棘手的拦截器问题?欢迎在评论区交流! 🚀