您好,登录后才能下订单哦!
密码登录
登录注册
点击 登录注册 即表示同意《亿速云用户服务条款》
# 如何用Vue封装Axios请求
## 前言
在现代前端开发中,网络请求是必不可少的部分。Axios作为当前最流行的HTTP客户端之一,以其简洁的API和强大的功能被广泛使用。而在Vue项目中,合理地封装Axios不仅能提高代码复用性,还能统一管理请求逻辑。本文将详细介绍如何在Vue项目中优雅地封装Axios请求。
## 一、为什么需要封装Axios
### 1.1 原始Axios使用的痛点
直接使用Axios虽然简单,但在实际项目中会面临:
- 每个请求都需要重复配置基础URL、headers等
- 缺乏统一的错误处理机制
- 难以集中管理API接口
- 不方便添加全局loading状态
- 难以实现请求取消等功能
### 1.2 封装带来的优势
通过封装可以实现:
- **统一配置**:基础路径、超时时间等
- **拦截器管理**:请求/响应拦截处理
- **API集中管理**:所有接口统一维护
- **更好的扩展性**:便于添加新功能
## 二、基础封装实现
### 2.1 创建axios实例
首先在项目中创建`src/utils/request.js`文件:
```javascript
import axios from 'axios'
// 创建axios实例
const service = axios.create({
baseURL: process.env.VUE_APP_BASE_API, // 从环境变量获取基础URL
timeout: 10000 // 请求超时时间
})
// 请求拦截器
service.interceptors.request.use(
config => {
// 在发送请求前可以做些什么
// 例如:添加token
const token = localStorage.getItem('token')
if (token) {
config.headers['Authorization'] = `Bearer ${token}`
}
return config
},
error => {
// 对请求错误做些什么
return Promise.reject(error)
}
)
// 响应拦截器
service.interceptors.response.use(
response => {
// 对响应数据做点什么
const res = response.data
// 假设后端返回的数据格式为 { code: 200, data: {}, message: '' }
if (res.code !== 200) {
// 处理业务错误
return Promise.reject(new Error(res.message || 'Error'))
} else {
return res.data
}
},
error => {
// 对响应错误做点什么
if (error.response) {
// 处理HTTP状态码错误
switch (error.response.status) {
case 401:
// 跳转到登录页
break
case 403:
// 提示权限不足
break
case 404:
// 资源不存在
break
case 500:
// 服务器错误
break
}
}
return Promise.reject(error)
}
)
export default service
创建src/api
目录,按模块划分API:
// src/api/user.js
import request from '@/utils/request'
export function login(data) {
return request({
url: '/user/login',
method: 'post',
data
})
}
export function getUserInfo() {
return request({
url: '/user/info',
method: 'get'
})
}
在请求拦截器中:
let loadingInstance
service.interceptors.request.use(config => {
loadingInstance = Loading.service({
lock: true,
text: '加载中...',
background: 'rgba(0, 0, 0, 0.7)'
})
return config
})
service.interceptors.response.use(
response => {
loadingInstance.close()
return response
},
error => {
loadingInstance.close()
return Promise.reject(error)
}
)
const pendingMap = new Map()
const getPendingKey = (config) => {
return [config.method, config.url].join('&')
}
service.interceptors.request.use(config => {
const key = getPendingKey(config)
if (pendingMap.has(key)) {
const cancel = pendingMap.get(key)
cancel()
pendingMap.delete(key)
}
config.cancelToken = new axios.CancelToken(cancel => {
pendingMap.set(key, cancel)
})
return config
})
service.interceptors.response.use(response => {
const key = getPendingKey(response.config)
pendingMap.delete(key)
return response
})
const retryDelay = 1000 // 重试延迟
const retryCount = 3 // 最大重试次数
service.interceptors.response.use(undefined, error => {
const config = error.config
if (!config || !config.retry) return Promise.reject(error)
config.__retryCount = config.__retryCount || 0
if (config.__retryCount >= retryCount) {
return Promise.reject(error)
}
config.__retryCount += 1
return new Promise(resolve => {
setTimeout(() => resolve(service(config)), retryDelay)
})
})
import { login } from '@/api/user'
export default {
methods: {
async handleLogin() {
try {
const res = await login({
username: 'admin',
password: '123456'
})
console.log('登录成功', res)
} catch (error) {
console.error('登录失败', error)
}
}
}
}
// store/modules/user.js
import { login, getUserInfo } from '@/api/user'
const actions = {
login({ commit }, userInfo) {
return new Promise((resolve, reject) => {
login(userInfo).then(res => {
commit('SET_TOKEN', res.token)
resolve()
}).catch(error => {
reject(error)
})
})
}
}
完整的封装示例可以参考以下结构:
src/
├── api/
│ ├── user.js
│ ├── product.js
│ └── ...
├── utils/
│ ├── request.js
│ └── ...
通过合理的封装,我们可以将Axios的强大功能与Vue的响应式特性完美结合,构建出健壮、易维护的网络请求层。本文介绍的方法只是基础实现,实际项目中可以根据需求进一步扩展和完善。希望本文能帮助你更好地组织Vue项目中的网络请求代码。 “`
这篇文章总计约1900字,涵盖了从基础封装到高级技巧的完整内容,采用Markdown格式编写,包含代码块、标题层级和列表等标准Markdown元素。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。