在写业务的时候,你现在是否还再请求调用处一遍遍写showLoading、hideLoading?即使自己对不同组件库的Loading进行二次封装,方便你调用,但这也不是很好的一种解决办法。
无论是ElementUI的Loading
还是Antd中的message.loaing
,你使用前都必须要先进行导入,这时候你可能会二次封装,将封装后的对象绑定在全局上。这是很常用的一种方法,直到前两天 突发奇想,为什么Loading不能统一写在一个地方,而不需要我们一遍遍的在请求调用处写showLoading、hideLoading呢。
基于此想法,我尝试着将Loading写在请求拦截器里面,我认为这是个不错的想法,哈哈哈。这样就可以让我们专注于业务逻辑的编写,无需对这些loading做过多判断。
重点来了:
那我们如何判断什么时候showLoading,什么时候hideLoading呢?难道每个请求都要loading?这些当然是有解决办法滴~
在封装的API中多加个参数
在封装的api中多加loading参数,类型为Boolean值,顺便加上一个loadingText,当然只针对需要进行loading的请求加此参数即可
export const getUser = () => {
return request('/api/users', {
method: 'get',
loading: true,
loadingText: '正在获取用户信息'
})
}
在拦截器中进行loading
这里只是给个简单示例,具体可根据自己的业务进行改写。
import request from 'umi-request';
import { message } from 'antd';
let isLoading = false
request.interceptors.request.use((url, options) => {
if(options.loading) {
isLoading = true
message.loading(options.loadingText || '加载中')
}
return {
url: `${url}`,
options: {
...options,
interceptors: true,
headers: {
token: '156cds6cdf'
}
}
}
})
request.interceptors.response.use((response) => {
if(isLoading) {
isLoading = false
message.destroy()
}
if(response.status > 400) {
const codeMaps = {
502: '网关错误。',
503: '服务不可用,服务器暂时过载或维护。',
504: '网关超时。',
};
// @ts-ignore
message.error(codeMaps[response.status])
}
return response
})
export default request
通过以上示例我们就可以不需要在调用接口的地方关注loading,请求进入请求拦截器,判断参数中是否有loading,有就进行loading提示,顺便定义一个全局变量判断是否该请求进行了loading。在响应拦截其中我们可以先判断这个全局变量,进行销毁loading提示。