使用 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">)。
<ul>
<li>HTML 中添加一个全局进度条元素(建议放在 <code> 顶部):
<div id="global-loading" class="loading-bar" style="display:none;"></div>
.loading-bar {
position: fixed;
top: 0;
left: 0;
height: 3px;
background: #409eff;
width: 0%;
z-index: 9999;
transition: width 0.2s ease-out;
}
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 {
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 项目中的补充建议
框架项目中,不建议把进度条逻辑耦合进组件内部。保持它作为“基础设施”存在:
- Vue:在
main.js或plugins/http.js中统一配置 axios/NProgress - React:在自定义 Hook(如
useApi)或服务层(apiClient.js)中封装 - 如需手动控制(比如某个按钮点击才显示),可暴露
startLoading()/finishLoading()方法供业务调用











