用Axios Element 实现全局的请求 loading


demo in github
背景
业务需求是这样子的,每当发请求到后端时就触发一个全屏的 loading,多个请求合并为一次 loading。
现在项目中用的是 vue 、axios、element等,所以文章主要是讲如果使用 axios 和 element 实现这个功能。
分析
首先,请求开始的时候开始 loading, 然后在请求返回后结束 loading。重点就是要拦截请求和响应。
然后,要解决多个请求合并为一次 loading。
最后,调用element 的 loading 组件即可。
拦截请求和响应
axios 的基本使用方法不赘述。笔者在项目中使用 axios 是以创建实例的方式。
// 创建axios实例
const $ = axios.create({
baseURL: `${URL_PREFIX}`,
timeout: 15000
})
然后再封装 post 请求(以 post 为例)
export default {
post: (url, data, config = { showLoading: true }) => $.post(url, data, config)
}
axios 提供了请求拦截和响应拦截的接口,每次请求都会调用showFullScreenLoading
方法,每次响应都会调用tryHideFullScreenLoading()
方法
// 请求拦截器
$.interceptors.request.use((config) => {
showFullScreenLoading()
return config
}, (error) => {
return Promise.reject(error)
})
// 响应拦截器
$.interceptors.response.use((response) => {
tryHideFullScreenLoading()
return response
}, (error) => {
return Promise.reject(error)
})
那么showFullScreenLoading
tryHideFullScreenLoading()
要干的事儿就是将同一时刻的请求合并。声明一个变量needLoadingRequestCount
,每次调用showFullScreenLoading
方法 needLoadingRequestCount + 1
。调用tryHideFullScreenLoading()
方法,needLoadingRequestCount - 1
。needLoadingRequestCount
为 0 时,结束 loading。
let needLoadingRequestCount = 0
export function showFullScreenLoading() {
if (needLoadingRequestCount === 0) {
startLoading()
}
needLoadingRequestCount++
}
export function tryHideFullScreenLoading() {
if (needLoadingRequestCount <= 0) return
needLoadingRequestCount--
if (needLoadingRequestCount === 0) {
endLoading()
}
}
startLoading()
和endLoading()
就是调用 element 的 loading 方法。
import { Loading } from 'element-ui'
let loading
function startLoading() {
loading = Loading.service({
lock: true,
text: '加载中……',
background: 'rgba(0, 0, 0, 0.7)'
})
}
function endLoading() {
loading.close()
}
到这里,基本功能已经实现了。每发一个 post 请求,都会显示全屏 loading。同一时刻的多个请求合并为一次 loading,在所有响应都返回后,结束 loading。
功能增强
实际上,现在的功能还差一点。如果某个请求不需要 loading 呢,那么发请求的时候加个 showLoading: false
的参数就好了。在请求拦截和响应拦截时判断下该请求是否需要loading,需要 loading 再去调用showFullScreenLoading()
方法即可。
在封装 post 请求时,已经在第三个参数加了 config 对象。config 里包含了 showloading
。然后在拦截器中分别处理。
// 请求拦截器
$.interceptors.request.use((config) => {
if (config.showLoading) {
showFullScreenLoading()
}
return config
})
// 响应拦截器
$.interceptors.response.use((response) => {
if (response.config.showLoading) {
tryHideFullScreenLoading()
}
return response
})
我们在调用 axios 时把 config 放在第三个参数中,axios 会直接把 showloading 放在请求拦截器的回调参数里,可以直接使用。在响应拦截器中的回调参数 response 中则是有一个 config 的 key。这个 config 则是和请求拦截器的回调参数 config 一样。
更新:2018-6-7
合并一定间隔时间内请求的 loading
上面的代码已经实现了将有时间重合的 loading 合并,什么意思呢?请看下图

在 request1 的 loading 还没结束时,request2 的 loading 已经开始。这种情况 request1 和 request2 在时间上有一定的重合,所以 loading 可以合并。
那么 request3 是在 request2 结束后 100ms 开始 loading.这时你会发现 loading 两次,并且中间有一次极短的闪烁,这当然是很不好的体验了。
我们只需要修改 tryHideFullScreenLoading 即可:
export function tryHideFullScreenLoading() {
if (needLoadingRequestCount <= 0) return
needLoadingRequestCount--
if (needLoadingRequestCount === 0) {
_.debounce(tryCloseLoading, 300)()
}
}
const tryCloseLoading = () => {
if (needLoadingRequestCount === 0) {
loading.close()
}
}
在之前的版本中,tryHideFullScreenLoading 方法会判断 needLoadingRequestCount === 0 立即关闭 loading。现在使用 lodash. debounce,延迟 300ms 再调用 tryCloseLoading 方法。
现在 300ms 间隔内的 loading 也就合并为一次啦……
用Axios Element 实现全局的请求 loading的更多相关文章
- AngularJS 拦截器实现全局$http请求loading效果
日常项目开发中,当前端需要和后端进行数据交互时,为了友好的UI效果,一般都会在前端加个loading的状态提示(包括进度条或者icon显示),数据传输或交互完成之后,再隐藏/删除loading提示. ...
- AXIOS构建请求处理全局loading状态&&AXIOS避免重复请求loading多次出现
一般情况下,在 vue 中结合 axios 的拦截器控制 loading 展示和关闭,是这样的:在 App.vue 配置一个全局 loading. <div class="app&qu ...
- Axios使用拦截器全局处理请求重试
Axios拦截器 Axios提供了拦截器的接口,让我们能够全局处理请求和响应.Axios拦截器会在Promise的then和catch调用前拦截到. 请求拦截示例 axios.interceptors ...
- 前端MVC Vue2学习总结(六)——axios与跨域HTTP请求、Lodash工具库
一.axios Vue更新到2.0之后宣告不再对vue-resource更新,推荐使用axios,axios是一个用于客户端与服务器通信的组件,axios 是一个基于Promise 用于浏览器和 no ...
- React、Vue添加全局的请求进度条(nprogress)
全局的请求进度条,我们可以使用nprogress来实现,效果如下: 首先需要安装插件: npm i nprogress -S 然后使用的时候主要有两种方式,第一种是切换页面的时候,第二种则是请求接口的 ...
- vue2 自定义全局组件(Loading加载效果)
vue2 自定义全局组件(Loading加载效果) github地址: https://github.com/ccyinghua/custom-global-component 一.构建项目 vue ...
- axios 是如何封装 HTTP 请求的
原载于 TutorialDocs 网站的文章<How to Implement an HTTP Request Library with Axios>.译者:zhangbao90shttp ...
- Jquery Ajax简单封装(集中错误、请求loading处理)
Jquery Ajax简单封装(集中错误.请求loading处理) 对Jquery Ajax做了简单封装,错误处理,请求loading等,运用到项目中集中处理会很方便. 技术层面没有什么好说的,请求是 ...
- FastAPI实践项目:SayHello(FastAPI + vue.js + axios + element ui)
目录 简介 翻版 VS 本尊 后端服务 源码 接下来 简介 这次带来的是FastAPI + vue.js + axios + element ui (一个html文件里使用的) 实现的<Flas ...
随机推荐
- MDC的使用(Mapped Diagnostic Context)的使用
通常我们可能会有大量的任务需要提交提交到线程池执行,但是此时如果不对日志添加唯一标识进行区分的话回到错乱一坨无法进行查看.因此可以对每一天日志添加唯一的标识,例如使用userid作为日志的唯一标志.这 ...
- Laravel小项目之第4节 Laravel-通过表单实现新增及操作状态提示功能
第4节 Laravel-通过表单实现新增及操作状态提示功能 4.1 显示新增表单视图 4.2 通过模型实现新增 4.3 操作状态提示 4.1 显示新增表单视图 修改边栏的链接 \resources\v ...
- Spring配置文件和SpringMVC配置文件 web.xml配置文件 保存自用
话不多说,最近在周末自己抽时间写一些框架做的系统,当所有东西都需要自己配置时候发现自己压根记不住这么多类和路径,所以日常总结就变得尤为重要了 db-config.properties 将配置文件常量提 ...
- pacman详解及常见问题
安装软件包:软件包有很多可选依赖,是为软件提供额外功能, 安装软件时pacman 会输出可选依赖, 但不会在 pacman.log中,浏览安装软件的可选以来可用pacman -Si得到可选依赖的简短描 ...
- 【Codeforces Round 1110】Codeforces Global Round 1
Codeforces Round 1110 这场比赛只做了\(A\).\(B\).\(C\),排名\(905\),不好. 主要的问题在\(D\)题上,有\(505\)人做出,但我没做出来. 考虑的时候 ...
- 在 Virtual Box 安装 Mac Os 并安装 Qt 开发应用
导读 由于 Beslyric-for-X 项目开发需要,开始尝试在 Mac Os 下开发 Qt 应用.尝试成功后,记录于此,希望对有类似需求的人有所帮助. 本文以开发 Beslyric-for-X 为 ...
- BZOJ4883 棋盘上的守卫 基环树、Kruskal
题目传送门:https://www.lydsy.com/JudgeOnline/problem.php?id=4883 题意:给出一个$N \times M$的棋盘,每个格子有权值.你需要每一行选中一 ...
- 关于小程序登录时获取openId和unionId走过的坑
目前的项目是在做小程序这方面的,接触过的人应该都知道,同一个微信开放平台下的相同主体的App.公众号.小程序的unionid是相同的,这样就可以锁定是不是同一个用户.微信针对不同的用户在不同的应用下都 ...
- [Spark][Python]DataFrame select 操作例子
[Spark][Python]DataFrame中取出有限个记录的例子 的 继续 In [4]: peopleDF.select("age")Out[4]: DataFrame[a ...
- vue 路由拦截、axios请求拦截
路由拦截 项目中,有些页面需要登录后才能进入,例如,在某页面A,用户在操作前需要先进入登录页(此时需要将上一页的地址(/survey/start)作为query存入login页面的地址中,如: htt ...