分析
页面在加载数据请求后端接口时,如果请求时间过长页面就会有一个白屏状态,尤其是vue项目使用异步组件的时候,组件加载都会有一个空白数据页面,所以考虑写一个loading方法,然后在需要的地方调用,但是这个写的话每个页面都要调用一次,所以需要考虑在接口请求时和响应时来统一管理加载状态。
实现
因为项目用的是axios库,所以在axios的全局的请求和响应方法中来开启和关闭loading状态,通过vuex或者pina来管理这个加载状态,这样在整个项目中都能访问到这个状态,因为项目中使用的组件库是element-plus,所以我是通过给router-view的父盒子绑定一个加载指令来实现的。
axios.interceptors.request.use(
function(config) {
store.commit("setApiLoading", true)
return config
},function(err) {
return Promise.reject(err)
}
)
axios.interceptors.response.use(
function(response) {
store.commit("setApiLoading", false)
return response
},function(err) {
store.commit("setApiLoading", false)
return Promise.reject(err)
}
)
因为接口响可能会有失败状态,所以需要在接口响应失败时也关掉加载状态。
问题
但是页面中通常存在一个组件调用多个接口数据的情况,这个时候组件的加载状态就会出现频繁的开启和关闭,造成页面闪动加载的情况,怎么才能让加载状态不频繁调用呢,我考虑的是在接口调用和响应时加一个定时器来延时开启loading状态,如果第二次请求时定时器存在就清除定时器,这样第一次的定时器还没被执行就清除了,就不会被执行,具体定时器的时间戳传多少,可以根据接口响应时间快慢来决定。
axios.interceptors.request.use(
function(config) {
if(requestTimer) {
// 解决接口请求时间过短,loading闪烁问题
clearTimeout(requestTimer)
requestTimer = null
}
store.commit("setApiLoading", true)
return config
},function(err) {
return Promise.reject(err)
}
)
axios.interceptors.response.use(
function(response) {
requestTimer = setTimeout(() => {
store.commit("setApiLoading", false)
requestTimer = null
}, 200)
return response
},function(err) {
store.commit("setApiLoading", false)
return Promise.reject(err)
}
)
在页面中绑定加载状态:
<el-container
v-loading="pageLoading"
>
<router-view> </router-view>
</el-container>
这样搞 ,页面在一次请求多个请求时就不会频繁的触发加载状态了,虽然同时调用的接口很多时,加载闪动给用户的感觉也不是太明显了。