Axios封装, 让你的请求更加优雅

封装 axios 需要具备以下几个功能:

  1. 请求超时时间设置
  2. 根据项目环境设置请求路径
  3. 请求拦截器:自动添加 Token
  4. 响应拦截器:处理响应状态码或数据格式化
  5. 请求队列实现 loading 效果
  6. 取消请求功能:页面切换时取消未完成的请求

下面是一个完整的 axios 封装示例,包含这些功能:

1. 安装依赖

复制代码
npm install axios nprogress

nprogress 是一个用于显示加载进度条的库,可以帮助实现 loading 效果。

2. 封装 axios

js 复制代码
// src/utils/request.js
import axios from 'axios';
import NProgress from 'nprogress';
import 'nprogress/nprogress.css';

// 设置取消请求的 token
const CancelToken = axios.CancelToken;
let pendingRequests = new Map(); // 用于存储请求队列

// 添加请求到队列
const addRequestToQueue = (config) => {
  const requestKey = `${config.method}:${config.url}`;
  config.cancelToken = new CancelToken((cancel) => {
    if (!pendingRequests.has(requestKey)) {
      pendingRequests.set(requestKey, cancel);
    }
  });
};

// 移除队列中的请求
const removeRequestFromQueue = (config) => {
  const requestKey = `${config.method}:${config.url}`;
  if (pendingRequests.has(requestKey)) {
    const cancel = pendingRequests.get(requestKey);
    cancel(requestKey);
    pendingRequests.delete(requestKey);
  }
};

// 清空请求队列(用于页面切换时取消请求)
export const clearRequestQueue = () => {
  pendingRequests.forEach((cancel, key) => {
    cancel(key);
  });
  pendingRequests.clear();
};

// 根据环境变量设置基础URL
const baseURL = process.env.NODE_ENV === 'production' ? 'https://api.production.com' : 'https://api.development.com';

// 创建 axios 实例
const service = axios.create({
  baseURL: baseURL,
  timeout: 5000, // 超时时间
  headers: {
    'Content-Type': 'application/json',
  }
});

// 请求拦截器
service.interceptors.request.use(
  (config) => {
    // 启动进度条
    NProgress.start();

    // 自动添加 Token 到请求头
    const token = localStorage.getItem('token');
    if (token) {
      config.headers['Authorization'] = `Bearer ${token}`;
    }

    // 添加请求到队列,防止重复请求
    removeRequestFromQueue(config);
    addRequestToQueue(config);

    return config;
  },
  (error) => {
    // 关闭进度条
    NProgress.done();
    return Promise.reject(error);
  }
);

// 响应拦截器
service.interceptors.response.use(
  (response) => {
    // 关闭进度条
    NProgress.done();

    // 请求成功后移除队列中的该请求
    removeRequestFromQueue(response.config);

    const res = response.data;
    
    // 自定义状态码处理
    if (res.code !== 200) {
      // 错误处理
      console.error('Error:', res.message);
      
      // 比如处理 token 过期
      if (res.code === 401) {
        console.error('Token expired, redirecting to login...');
        // 可以执行登出操作,或跳转到登录页面
      }
      return Promise.reject(new Error(res.message || 'Error'));
    } else {
      return res; // 返回处理过的数据
    }
  },
  (error) => {
    // 关闭进度条
    NProgress.done();

    // 请求失败时清除队列中的该请求
    removeRequestFromQueue(error.config || {});

    return Promise.reject(error);
  }
);

export default service;

3. 使用导航守卫取消未完成请求

在页面切换时,通过 Vue Router 的导航守卫取消未完成的请求。

js 复制代码
// src/router/index.js
import Vue from 'vue';
import Router from 'vue-router';
import { clearRequestQueue } from '@/utils/request'; // 引入清除请求队列的函数

Vue.use(Router);

const router = new Router({
  routes: [
    // 定义你的路由
  ]
});

router.beforeEach((to, from, next) => {
  // 页面切换前取消所有未完成的请求
  clearRequestQueue();
  next();
});

export default router;

4. 在组件中使用 axios 封装

在 Vue 组件中使用封装的 axios

vue 复制代码
<template>
  <div>
    <h1>{{ data }}</h1>

  </div>

</template>

<script>
import service from '@/utils/request';

export default {
  data() {
    return {
      data: null,
    };
  },
  async created() {
    try {
      const response = await service.get('/some-endpoint');
      this.data = response.data;
    } catch (error) {
      console.error('Error fetching data:', error);
    }
  }
};
</script>

5. 效果解析

  1. 请求超时 :在 axios 实例中通过 timeout: 5000 设置了 5 秒的请求超时。
  2. 根据环境设置请求路径 :使用 process.env.NODE_ENV 判断当前环境,并设置 baseURL
  3. 请求拦截:自动添加 Token :每次请求会从 localStorage 中获取 Token 并添加到 Authorization 请求头中。
  4. 响应拦截:处理状态码与格式化数据:统一处理了响应的状态码,如果不是 200,会抛出错误。
  5. 请求队列与 loading 效果 :使用 nprogress 显示加载进度条,且通过请求队列管理,防止重复请求。
  6. 取消请求功能 :在每次请求时生成一个取消 token,并在页面切换时通过导航守卫取消未完成的请求。

通过这种封装,你可以有效管理请求的全生命周期,并确保在项目中对 HTTP 请求的处理变得更高效、可维护。

相关推荐
掘了4 小时前
「2025 年终总结」在所有失去的人中,我最怀念我自己
前端·后端·年终总结
崔庆才丨静觅4 小时前
实用免费的 Short URL 短链接 API 对接说明
前端
崔庆才丨静觅4 小时前
5分钟快速搭建 AI 平台并用它赚钱!
前端
崔庆才丨静觅5 小时前
比官方便宜一半以上!Midjourney API 申请及使用
前端
Moment5 小时前
富文本编辑器在 AI 时代为什么这么受欢迎
前端·javascript·后端
崔庆才丨静觅5 小时前
刷屏全网的“nano-banana”API接入指南!0.1元/张量产高清创意图,开发者必藏
前端
剪刀石头布啊5 小时前
jwt介绍
前端
爱敲代码的小鱼5 小时前
AJAX(异步交互的技术来实现从服务端中获取数据):
前端·javascript·ajax
Cobyte5 小时前
AI全栈实战:使用 Python+LangChain+Vue3 构建一个 LLM 聊天应用
前端·后端·aigc
NEXT066 小时前
前端算法:从 O(n²) 到 O(n),列表转树的极致优化
前端·数据结构·算法