使用 axios 拦截器 + NProgress 可实现全局进度条:请求发起时调用 NProgress.start() 显示,响应返回(含错误)时调用 done() 隐藏;若用原生 fetch,则需手动封装并控制 DOM 进度条显隐与动画。

在前端用 JavaScript 实现接口请求的全局进度条加载动画,核心思路是:拦截所有请求(如通过 fetch 或 axios),在请求发起时显示进度条,在响应返回(无论成功或失败)时隐藏它,并配合 CSS 动画实现视觉上的“加载中”效果。
使用 axios 拦截器 + NProgress(推荐)
NProgress 是一个轻量、易用的全局进度条库,适配 AJAX 请求场景。配合 axios 的请求/响应拦截器,能自动控制进度条显隐和动画。
- 安装:
npm install nprogress - 引入并初始化(通常在入口文件如
main.js):import NProgress from 'nprogress'; import 'nprogress/nprogress.css'; // 可选:自定义样式或行为 NProgress.configure({ minimum: 0.1, easing: 'ease', speed: 300, showSpinner: false // 隐藏右侧小圆圈 }); - 添加 axios 拦截器:
// 请求开始前显示进度条 axios.interceptors.request.use(config => { NProgress.start(); return config; }); // 响应返回后隐藏进度条(注意:需对所有响应都调用 done) axios.interceptors.response.use( response => { NProgress.done(); return response; }, error => { NProgress.done(); // 错误时也要关闭,避免卡住 return Promise.reject(error); } );
纯原生 fetch + 手动控制进度条(无第三方库)
若不想引入额外依赖,可用 fetch 包装函数 + 简单 DOM 进度条(如固定顶部的 <div class="loading-bar">)。
- HTML 中添加一个全局进度条元素(建议放在
<body>顶部):<div id="global-loading" class="loading-bar" style="display:none;"></div>
- CSS 样式示例(带平滑过渡和动态宽度):
.loading-bar { position: fixed; top: 0; left: 0; height: 3px; background: #409eff; width: 0%; z-index: 9999; transition: width 0.2s ease-out; } - 封装 fetch 函数,统一控制显示/隐藏:
const loadingBar = document.getElementById('global-loading'); function showLoading() { loadingBar.style.display = 'block'; loadingBar.style.width = '10%'; // 模拟进度增长(可选,更真实) const timer = setInterval(() => { const w = parseFloat(loadingBar.style.width); if (w < 90) loadingBar.style.width = (w + 10) + '%'; }, 200); return () => { clearInterval(timer); loadingBar.style.width = '100%'; setTimeout(() => { loadingBar.style.display = 'none'; loadingBar.style.width = '0%'; }, 300); }; } async function apiFetch(url, options = {}) { const hide = showLoading(); try { const res = await fetch(url, options); hide(); return res; } catch (err) { hide(); throw err; } }
注意事项与优化点
-
防重复触发:多个并发请求时,避免多次调用
NProgress.start()导致进度条异常。NProgress 内部已处理,但自定义方案需加计数器(如请求进入 +1,完成 -1,为 0 时隐藏) -
跳过某些请求:如头像、静态资源等非关键接口,可在拦截器里通过 URL 或配置项(如
config.metadata?.noLoading)跳过进度条 - 用户体验细节:设置最小显示时间(如 300ms),防止请求太快导致进度条“闪一下”,影响观感
- 错误状态反馈:进度条收起后,建议配合 Toast 或 UI 提示明确告知用户失败原因,而非只靠进度条本身
Vue/React 项目中的补充建议
框架项目中,不建议把进度条逻辑耦合进组件内部。保持它作为“基础设施”存在:
立即学习“Java免费学习笔记(深入)”;
- Vue:在
main.js或plugins/http.js中统一配置 axios/NProgress - React:在自定义 Hook(如
useApi)或服务层(apiClient.js)中封装 - 如需手动控制(比如某个按钮点击才显示),可暴露
startLoading()/finishLoading()方法供业务调用


















