Vue3 请求后端 RESTful 接口的几种方案及优缺点对比

fetch API、axios、ky、vue-resource 等请求后端 RESTful 接口的几种方案及优缺点对比

在 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
npm install axios

示例代码

 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
npm install ky

示例代码

 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 项目的首选;对于轻量场景,fetchky 更合适; 而 vue-request 则在状态管理上有明显优势。多接口调用时,需根据依赖关系选择并发或顺序执行,并注意错误处理的完整性。

如果本文对您有所帮助,欢迎打赏支持作者!

Licensed under CC BY-NC-SA 4.0
最后更新于 2025-10-25 13:53
使用 Hugo 构建
主题 StackJimmy 设计