Vue.js Ajax(axios)
·
在 Vue.js 中,Axios 是最常用的 HTTP 客户端库,用于发送 Ajax 请求。它基于 Promise,支持浏览器和 Node.js,具有拦截器、自动转换 JSON、取消请求等强大功能。
一、安装
npm install axios
# 或
yarn add axios
二、基础用法
1. 在组件中直接发送请求
<template>
<div>
<button @click="fetchData">加载数据</button>
<ul v-if="list">
<li v-for="item in list" :key="item.id">{{ item.name }}</li>
</ul>
</div>
</template>
<script setup>
import { ref } from 'vue';
import axios from 'axios';
const list = ref(null);
const loading = ref(false);
const fetchData = async () => {
loading.value = true;
try {
const response = await axios.get('https://api.example.com/users');
list.value = response.data;
} catch (error) {
console.error('请求失败:', error);
} finally {
loading.value = false;
}
};
</script>
2. 常用请求方法
// GET
axios.get('/user?id=123')
.then(response => console.log(response.data));
// GET (带 params)
axios.get('/user', { params: { id: 123 } })
.then(response => console.log(response.data));
// POST
axios.post('/user', { name: 'Tom', age: 20 })
.then(response => console.log(response.data));
// PUT / PATCH
axios.put('/user/123', { name: 'Jerry' });
axios.patch('/user/123', { age: 21 });
// DELETE
axios.delete('/user/123');
// 并发请求
axios.all([
axios.get('/users'),
axios.get('/posts')
]).then(axios.spread((usersRes, postsRes) => {
console.log(usersRes.data, postsRes.data);
}));
三、创建 Axios 实例(推荐)
在实际项目中,不要直接在组件中 import axios,而是创建一个自定义实例,配置基础 URL、超时、拦截器等。
1. 创建实例
// src/utils/request.js
import axios from 'axios';
const request = axios.create({
baseURL: process.env.VUE_APP_API_BASE_URL || 'https://api.example.com',
timeout: 5000, // 超时时间
headers: {
'Content-Type': 'application/json',
},
});
export default request;
2. 在组件中使用
<script setup>
import request from '@/utils/request';
const getUser = async () => {
const res = await request.get('/user/123');
console.log(res.data);
};
</script>
四、请求与响应拦截器
拦截器是 Axios 最强大的功能,用于统一处理请求头、错误、Token等。
1. 添加拦截器
// src/utils/request.js
import axios from 'axios';
import { ElMessage } from 'element-plus'; // 假设使用 Element Plus
const request = axios.create({
baseURL: '/api',
timeout: 5000,
});
// 请求拦截器:发送前处理
request.interceptors.request.use(
(config) => {
// 1. 添加 Token
const token = localStorage.getItem('token');
if (token) {
config.headers.Authorization = `Bearer ${token}`;
}
// 2. 处理 GET 请求的 params
if (config.method === 'get') {
config.params = { ...config.params, timestamp: Date.now() };
}
return config;
},
(error) => {
return Promise.reject(error);
}
);
// 响应拦截器:收到响应后处理
request.interceptors.response.use(
(response) => {
// 假设后端统一返回 { code: 200, data: ..., msg: 'success' }
const { code, data, msg } = response.data;
if (code === 200) {
return data; // 直接返回 data,组件中无需再解构
} else {
ElMessage.error(msg || '请求失败');
return Promise.reject(new Error(msg));
}
},
(error) => {
// 处理 HTTP 状态码错误
if (error.response) {
const { status } = error.response;
switch (status) {
case 401:
ElMessage.error('未登录,请重新登录');
localStorage.removeItem('token');
// 跳转登录页
// router.push('/login');
break;
case 403:
ElMessage.error('无权限访问');
break;
case 404:
ElMessage.error('资源不存在');
break;
case 500:
ElMessage.error('服务器错误');
break;
default:
ElMessage.error('网络错误');
}
} else if (error.request) {
// 请求已发送但未收到响应
ElMessage.error('网络超时,请检查连接');
} else {
// 请求配置出错
ElMessage.error('请求配置错误');
}
return Promise.reject(error);
}
);
export default request;
2. 组件中使用(简化)
<script setup>
import request from '@/utils/request';
const fetchData = async () => {
try {
// 拦截器已经处理了 token 和错误,这里直接拿到 data
const data = await request.get('/users');
console.log(data);
} catch (error) {
// 错误已在拦截器中处理,这里可选做额外逻辑
}
};
</script>
五、取消请求
在组件卸载或用户快速切换时,取消未完成的请求,避免内存泄漏和状态错乱。
1. 使用 AbortController(推荐)
<script setup>
import { ref, onUnmounted } from 'vue';
import axios from 'axios';
const data = ref(null);
const controller = new AbortController();
const fetchData = async () => {
try {
const res = await axios.get('/users', {
signal: controller.signal, // 绑定信号
});
data.value = res.data;
} catch (error) {
if (axios.isCancel(error)) {
console.log('请求已取消:', error.message);
} else {
console.error('请求失败:', error);
}
}
};
// 组件卸载时取消请求
onUnmounted(() => {
controller.abort();
});
</script>
2. 使用 CancelToken(旧版,Vue 2 常用)
const CancelToken = axios.CancelToken;
const source = CancelToken.source();
axios.get('/users', {
cancelToken: source.token
}).catch(thrown => {
if (axios.isCancel(thrown)) {
console.log('Request canceled', thrown.message);
}
});
// 取消
source.cancel('Operation canceled by the user.');
六、封装 API 模块(最佳实践)
将 API 请求按模块拆分,统一管理。
// src/api/user.js
import request from '@/utils/request';
export function login(data) {
return request({
url: '/auth/login',
method: 'post',
data,
});
}
export function getUserInfo() {
return request({
url: '/user/info',
method: 'get',
});
}
export function updateUser(data) {
return request({
url: '/user/update',
method: 'put',
data,
});
}
<!-- 组件中使用 -->
<script setup>
import { login, getUserInfo } from '@/api/user';
const handleLogin = async () => {
const res = await login({ username: 'tom', password: '123' });
console.log(res);
};
</script>
七、Vue 2 vs Vue 3 差异
| 特性 | Vue 2 | Vue 3 |
|---|---|---|
| 导入方式 | import axios from 'axios' |
同上 |
| 生命周期 | mounted() |
onMounted() |
| 取消请求 | CancelToken |
AbortController (推荐) |
| 响应拦截器 | 同上 | 同上 |
八、总结
| 场景 | 推荐方案 |
|---|---|
| 简单请求 | 直接 axios.get/post |
| 项目级请求 | 创建 axios.create() 实例 |
| 统一处理 Token/错误 | 请求/响应拦截器 |
| 取消请求 | AbortController (Vue 3) |
| 代码组织 | 按模块封装 API 文件 |
核心流程:
- 安装 Axios。
- 创建自定义实例(配置 baseURL、timeout)。
- 添加拦截器(统一处理 Token、错误)。
- 封装 API 模块(按业务拆分)。
- 在组件中调用 API。
Axios 是 Vue 项目处理网络请求的事实标准,配合拦截器和模块化封装,可以极大提升开发效率和代码可维护性。
更多推荐


所有评论(0)