在 Vue3 项目中,与后端 RESTful 接口交互是核心需求之一。以下是几种常见方案,包括原生 API 和第三方库,并对比其优缺点,同时介绍多接口调用的实现方式。
常用请求方案及示例
原生 fetch API (浏览器内置)
fetch 是浏览器原生支持的 HTTP 请求 API,无需额外安装依赖,基于 Promise 实现。
示例代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
// 封装请求函数
const fetchData = async (url, method = 'GET', data = null) => {
const options = {
method,
headers: {
'Content-Type': 'application/json',
// 可添加认证信息(如 Token)
'Authorization': `Bearer ${localStorage.getItem('token')}`
}
};
if (data) options.body = JSON.stringify(data);
try {
const response = await fetch(url);
if (!response.ok) throw new Error(`HTTP error! Status: ${response.status}`);
return await response.json();
} catch (error) {
console.error('请求失败:', error);
throw error; // 抛出错误供调用方处理
}
};
|
使用示例:
1
2
3
4
5
6
7
8
9
|
// GET 请求
const getUser = async (id) => {
return await fetchData(`/api/users/${id}`);
};
// POST 请求
const createUser = async (userData) => {
return await fetchData('/api/users', 'POST', userData);
};
|
优点:
- 无需安装依赖,原生支持,体积小
- 基于 Promise,支持
async/await,语法简洁
缺点:
- 错误处理不直观(状态码 4xx / 5xx 不会触发
catch,需手动判断 response.ok)
- 不支持请求中断(AbortController 需额外实现)
- 无默认超时设置,需手动封装
- 不支持请求 / 响应拦截器,需手动实现
axios (第三方库,最常用)
axios 是基于 Promise 的 HTTP 客户端,支持浏览器和 Node.js,功能完善,社区活跃。
安装
示例代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
import axios from 'axios';
const request = axios.create({
baseURL: '/api', // 基础路径
timeout: 5000, // 超时时间
headers: {
'Content-Type': 'application/json'
}
});
// 请求拦截器(添加 Token 等)
request.interceptors.request.use(
(config) => {
const token = localStorage.getItem('token');
if (token) config.headers.Authorization = `Bearer ${token}`;
return config;
},
(error) => Promise.reject(error)
);
// 响应拦截器(统一处理错误)
request.interceptors.response.use(
(response) => response.data, // 直接返回数据体
(error) => {
if (error.response?.status === 401) {
// 处理未授权(如跳转到登录页)
router.push('/login');
}
return Promise.reject(error);
}
);
export default request;
|
使用示例:
1
2
3
4
5
6
7
8
9
10
11
|
import request from '@/utils/request';
// GET 请求
const getUser = (id) => {
return request.get(`/users/${id}`);
};
// POST 请求
const createUser = (userData) => {
return request.post('/users', userData);
};
|
优点:
- 支持请求 / 响应拦截器,便于统一处理 Token、错误等
- 内置超时设置、请求中断(CancelToken)
- 自动转换 JSON 数据,无需手动
JSON.parse
- 支持并发请求 (
axios.all)
- 浏览器端支持防止 XSRF 攻击
缺点:
- 需要额外安装依赖
- 配置相对复杂(但封装后易用性高)
vue-request (Vue 生态专用请求库)
vue-request 是基于 Vue3 Composition API 的请求库,集成了 loading 状态、缓存、重试等功能。
安装:
1
|
npm install vue-request
|
示例代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
import { useRequest } from 'vue-request';
import request from '@/utils/request'; // 基于 axios 封装的实例
// 获取用户信息
const { data, loading, error, run } = useRequest(
(id) => request.get(`/users/${id}`),
{
manual: true, // 手动触发请求
onSuccess: (result) => {
console.log('请求成功:', result);
}
}
);
|
使用示例:
1
2
3
|
const fetchUser = (userId) => {
run(userId); // 传入参数触发请求
};
|
优点:
- 与 Vue3 响应式系统深度集成,自动管理 loading、data、error 状态
- 支持缓存、防抖、节流、重试等高级功能
- 减少模板中重复的状态管理代码
缺点:
- 额外依赖,增加项目体积
- 学习成本略高,需理解其配置项
- 灵活性略低于
axios
ky (轻量级第三方库)
ky 是基于 fetch 的现代化 HTTP 客户端,API 简洁,体积小
安装:
示例代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
import ky from 'ky';
// 基础请求
const getUser = async (id) => {
return await ky.get(`/api/users/${id}`).json();
};
// 带配置的实例
const api = ky.create({
prefixUrl: '/api',
headers: {
'Authorization': `Bearer ${localStorage.getItem('token')}`
},
timeout: 5000
});
// 使用实例请求
const createUser = async (userData) => {
return await api.post('users', { json: userData }).json();
};
|
优点:
- 体积小,API 简洁,基于
fetch 但优化了缺陷(如 4xx/5xx 会触发错误)
- 内置 JSON 处理、超时设置、请求中断
- 支持拦截器(需通过
hooks 实现)
缺点:
- 生态不如 axios 完善,社区案例较少
- 拦截器功能相对简单
多接口调用场景的实现
实战用例可参考 Vue3 实战:多接口并发与界面渲染最佳实践
在实际开发中,经常需要处理多个接口的并发调用或顺序调用,以下是常见实现方式:
并发调用 (多个接口同时请求,全部完成后处理)
适合接口之间无依赖关系的场景,可提高效率。
示例(基于 axios):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
import axios from 'axios';
const fetchAllData = async () => {
try {
// 并发请求两个接口
const [userRes, postsRes] = await Promise.all([
axios.get('/api/users/1'),
axios.get('/api/posts')
]);
console.log('用户数据:', userRes.data);
console.log('文章数据:', postsRes.data);
} catch (error) {
console.error('任一请求失败:', error);
}
};
|
注意:
Promise.all 中任一请求失败会立即触发 catch,需确保接口独立性
- 若需忽略失败的请求,可使用
Promise.allSettled,然后过滤成功结果
顺序调用(接口按依赖关系依次请求)
适合后一个接口依赖前一个接口返回结果的场景(如先获取 Token,再用 Token 请求数据)。
示例(基于 axios):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
const fetchDataInOrder = async () => {
try {
// 第一步:获取 Token
const tokenRes = await axios.post('/api/login', { username: 'admin', password: '123' });
const token = tokenRes.data.token;
// 第二步:用 Token 请求用户信息
const userRes = await axios.get('/api/users/1', {
headers: { Authorization: `Bearer ${token}` }
});
console.log('用户信息:', userRes.data);
} catch (error) {
console.error('步骤失败:', error);
}
};
|
注意:
- 顺序调用会增加总耗时,需评估是否有优化空间(如能否通过后端接口合并减少请求)
- 可通过
async/await 嵌套或链式 then 实现,前者可读性更高。
方案选择建议
| 场景 |
推荐方案 |
理由 |
| 轻量项目,无复杂需求 |
fetch API |
无需依赖,满足基础需求 |
| 中大型项目,需统一拦截、并发控制 |
axios |
功能完善,生态成熟,社区支持好 |
| Vue3 项目,需频繁管理请求状态 |
vue-request |
与 Composition API 无缝集成,减少状态代码 |
追求轻量且需要 fetch 增强功能 |
ky |
体积小,API 简洁,修复了 fetch 缺陷 |
总结
选择请求方案时需结合项目规模、团队熟悉度和功能需求。axios 因其均衡的功能和广泛的社区支持,是大多数 Vue3 项目的首选;对于轻量场景,fetch 或 ky 更合适;
而 vue-request 则在状态管理上有明显优势。多接口调用时,需根据依赖关系选择并发或顺序执行,并注意错误处理的完整性。