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 请求的处理变得更高效、可维护。

相关推荐
ᥬ 小月亮几秒前
Ant design vue中的日期
前端·javascript·vue.js
拄杖盲学轻声码11 分钟前
【html网页制作】国庆节日主题网页制作含js轮播(5页面附效果源码)
前端·javascript·html
江凡心18 分钟前
Qt 每日面试题 -5
服务器·数据库·qt·学习·面试
you来有去23 分钟前
npm install报错npm ERR! Found: vite@4.5.0
前端·npm·node.js
www.www26 分钟前
获取鼠标当前位置上的元素
开发语言·javascript·ecmascript
等什么君!44 分钟前
初识Vue3(详细版)
前端·vue
会跳舞的小猴子1 小时前
echarts 导出pdf空白原因
javascript·pdf·echarts
程序员奇奥1 小时前
Vue中对数组变化监听
前端·javascript·vue.js
胡西风_foxww1 小时前
用css画一个loading
前端·css·loading·加载中
i80131 小时前
弹性盒模型关键几个点:
前端·javascript·css