封装axios实现全局loading,在一定程度上减少重复请求的发生

解决了 "在每个页面 / 按钮上手动绑定 loading" 的问题,大幅减少了重复代码
核心代码如下:
ini 复制代码
import axios from 'axios';
import { Loading } from 'element-ui';
// 定义不同API类型的超时时间(单位:毫秒)
const TIMEOUT_CONFIG = {
  default: 3000, // 默认超时时间
  fast: 1000,     // 快速API,简单查询等
  normal: 5000,  // 普通API,大多数业务接口
  slow: 10000,    // 慢速API,文件上传、大数据量处理
  critical: 15000 // 关键API,支付、重要业务处理
}

const service = axios.create({
  baseURL: process.env.VUE_APP_BASE_API, 
  timeout: TIMEOUT_CONFIG.default 
});

/**
 *  loading 计数
 *  loadingCount //请求次数,为0时,结束loading
 **/
 let loadingCount = 0
 let isLoading = false
 let loadingInstance = null
 const noLoadingApi = ['a','b','c'] // 禁止触发全局loading的路由
 const addLoading = (url) => {
 const result = noLoadingApi.includes(url)
  if(result){
    return;
  }
   loadingCount++
   if (!isLoading){
    loadingInstance = Loading.service({
      lock: true,
      background: 'rgba(0, 0, 0, 0.9)'
    })
    isLoading = true
   }
 }
 
 const closeLoading = (url) => {
 const result = url && noLoadingApi.includes(url)
  if(result){
    return;
  }
   loadingCount--
   if (loadingCount <= 0) {
    loadingInstance && loadingInstance.close()
    isLoading = false
   }
 }

service.interceptors.request.use(
  config => {
    // 定义关键API路径数组
    const CRITICAL_API_PATHS = ['a','b','c'];
    
    // 检查是否是关键API
    if (CRITICAL_API_PATHS.some(path => config.url.includes(path))) {
      config.timeout = TIMEOUT_CONFIG.critical
    }
    addLoading(config.url)
    //....根据需求自定义封装请求头
  
    return config;
  },
  error => {
    return Promise.reject(error);
  }
);

service.interceptors.response.use(
  response => {
    closeLoading(response.config.url)
    //...根据需求自定义封装响应头
  },
  error => {
    closeLoading()
    return Promise.reject(error);
  }
);

export default service;

1. 全局统一管理 loading,无需页面 / 按钮单独处理

代码通过 axios 的请求 / 响应拦截器,对所有经过 service 实例的请求进行统一拦截:

  • 请求发起时 :自动调用 addLoading 显示全局 loading(除非接口在 noLoadingApi 白名单中);
  • 请求完成时 (成功 / 失败):自动调用 closeLoading 关闭全局 loading(当所有并发请求都完成时)。

这种方式下,无论哪个页面、哪个按钮触发的请求,只要使用了这个 service 实例,都不需要在页面中手动写 loading.show()loading.hide(),完全由拦截器自动处理。

2. 避免了 "重复编写 loading 控制逻辑" 的冗余

如果没有这段代码,通常的做法是:

  • 在每个按钮点击事件中,先手动显示 loading;
  • 在请求的 then/catch 中手动隐藏 loading;
  • 还要处理多个请求并发时,loading 被提前关闭的问题(比如两个请求同时发起,第一个完成就关 loading,导致第二个请求无 loading)。

而这段代码通过 loadingCount 计数和拦截器统一控制,一次性解决了 "显示 / 隐藏时机""并发请求 loading 管理" 等问题,所有页面 / 按钮都能复用这套逻辑,无需重复编写。

3. 特殊场景通过配置排除,灵活性兼顾

代码中通过 noLoadingApi 数组定义了 "不需要 loading 的接口",对于这些特殊接口,无需在页面中单独处理,只需在全局配置中维护这个数组即可,进一步减少了页面级的重复配置。

总结

这段代码通过 "拦截器 + 全局配置" 的方式,实现了 loading 的 "一次编写,全项目复用",彻底避免了在每个页面、每个按钮中重复编写 loading 控制逻辑的工作,显著减少了冗余代码,同时还解决了并发请求下的 loading 显示问题,是一种高效的全局状态管理方案。

相关推荐
打小就很皮...11 小时前
React 项目开发指南:脚手架搭建、Axios 封装与 Gitee 远程仓库配置
react.js·gitee·axios
新晨4375 天前
Axios 拦截器
前端·axios
米欧11 天前
取消当前正在进行的所有接口请求
前端·javascript·axios
一雨方知深秋13 天前
AJAX学习 ---- axios体验
javascript·http·ajax·axios·url·catch·then
西洼工作室15 天前
前端接口安全与性能优化实战
前端·vue.js·安全·axios
柯腾啊16 天前
一文简单入门 Axios
前端·axios·apifox
Sheldon一蓑烟雨任平生21 天前
Vue 用户管理系统(路由相关练习)
vue.js·vue3·axios·json-server·vue-router·vue 路由·vue-link
沐雨橙风ιε1 个月前
防止表单重复提交功能简单实现
java·spring boot·ajax·axios·spring mvc
桃子不吃李子1 个月前
axios的二次封装
前端·学习·axios