共计 1849 个字符,预计需要花费 5 分钟才能阅读完成。
在基于 ArcoDesign 开发中后台应用时,全局网络请求进度条的控制是一个常见但容易被忽视的问题。今天我想分享一下我在实际项目中遇到的坑以及解决方案,希望能帮助到正在遇到类似问题的同学。

问题背景
首先说说为什么会遇到这个问题。在现代化的前端应用中,我们经常会有多个接口同时请求的情况。这时候如果每个请求都独立控制进度条,就会出现进度条闪烁、重复触发的问题。
- 页面加载时同时发起 3 个 API 请求,进度条会快速显示又隐藏 3 次
- 快速切换路由时,上一个页面的请求还没完成,新页面的请求又来了
- 某些请求非常快(比如 304 缓存),导致进度条刚出现就消失
这些问题都会给用户带来不好的体验,让人觉得应用很不稳定。
技术方案对比
针对这个问题,我调研了三种常见的解决方案:
- 纯 CSS 方案
- 优点:实现简单,无 JS 依赖
-
缺点:无法感知实际请求状态,容易出现假进度
-
Promise.all 封装
- 优点:能准确知道所有请求完成时机
-
缺点:需要改造所有请求调用方式,侵入性强
-
请求队列 + 计数器
- 优点:对现有代码改动小,能准确跟踪请求状态
- 缺点:实现稍复杂
经过实践,我选择了第三种方案,因为它对现有代码的侵入性最小,效果也最稳定。
核心实现
1. 请求计数器
首先我们需要一个全局的请求计数器,来跟踪当前活跃的请求数量。这里用 axios 的拦截器来实现:
let activeRequests = 0;
// 请求拦截器
axios.interceptors.request.use(config => {if (activeRequests++ === 0) {store.commit('showProgress');
}
return config;
});
// 响应拦截器
axios.interceptors.response.use(
response => {if (--activeRequests === 0) {store.commit('hideProgress');
}
return response;
},
error => {if (--activeRequests === 0) {store.commit('hideProgress');
}
return Promise.reject(error);
}
);
2. 状态管理
接下来我们需要在 Vuex 或 Pinia 中管理进度条状态:
// store/modules/loading.js
export default {state: () => ({
isLoading: false,
timer: null
}),
mutations: {showProgress(state) {clearTimeout(state.timer);
state.isLoading = true;
},
hideProgress(state) {
// 设置最小显示时长 500ms
state.timer = setTimeout(() => {state.isLoading = false;}, 500);
}
}
};
3. 组件集成
最后在 ArcoDesign 的进度条组件中使用这个状态:
<template>
<a-spin
:loading="isLoading"
tip="加载中..."
class="global-loading"
/>
</template>
<script>
import {mapState} from 'vuex';
export default {
computed: {...mapState('loading', ['isLoading'])
}
};
</script>
避坑指南
在实际实现过程中,我遇到了一些坑,这里分享给大家:
- SSR 场景
- 在服务端渲染时不能直接操作 DOM
-
解决方案:通过 process.client 判断环境
-
快速失败请求
- 404 等错误请求会导致进度条闪烁
-
解决方案:设置最小显示时长(上面代码已实现)
-
跨域请求
- OPTIONS 预检请求也会触发拦截器
- 解决方案:过滤掉 method 为 OPTIONS 的请求
性能优化
为了更好的用户体验,我做了以下优化:
- 设置 500ms 最小显示时长,避免进度条闪烁
- 使用防抖处理快速连续的请求
- 在慢速网络下显示百分比进度(需要后端支持)
扩展思考
未来还可以考虑以下增强功能:
- 结合 Sentry 监控,在请求异常时自动回收进度条
- 根据请求时间动态调整进度条速度
- 区分重要和非重要请求,非重要请求不触发进度条
总结
通过这个方案,我们实现了:
- 准确的全局请求状态跟踪
- 平滑的进度条显示 / 隐藏过渡
- 对现有代码的最小侵入性
实际使用下来,用户反馈加载体验明显改善,不再有之前的闪烁问题。希望这个方案对你也有帮助!
如果你有其他更好的解决方案,欢迎在评论区交流讨论。
正文完
发表至: 前端开发
近一天内
