element取消全局loading
背景
前两天在开发一个管理后台项目时, 遇到了一个问题,后端接口返回特别慢,由于该接口调用的是第三方API,无法通过后端去处理。此时想到用loading动画,但随之而来也产生了不少问题, 在此记录一下以方便大家能够遇到此类问题可以借鉴。
处理方案
在表格内添加loading
<el-table
v-loading="loading"
:data="tableData"
border
tooltip-effect="dark"
:row-class-name="tableRowClassName"
style="margin-top: 20px"
>
...
</el-table>
此种方式很简单,在请求开始前设置loading为true,结束后设置为false。element官网也有详细的概述,在此不过多描述。
在全局内容容器内添加动画
第一种方式确实简单,但开发后UI效果并不是特别理想,所以考虑在内容容器内添加loading。此时使用了以服务的方式加载loading。
但此时也出现了一些问题, 首先在请求开始后,立即切换到其它页面,此时还在显示全局loading。
而且再次切回该页面又会再次发起请求,loading显示位置也不正常。
切换路由是要取消请求和loading的,我们需要在组件路由生命周期内进行监听。在离开此路由时,取消此次请求。
以下为具体代码:
离开路由生命周期
beforeRouteLeave(to, from, next) {
// 导航离开该组件的对应路由时调用
// 可以访问组件实例 `this`
this.source.cancel("离开此页面取消请求");
next();
},
...
请求事件
getTable() {
const CancelToken = axios.CancelToken;
this.source = CancelToken.source();
const options = {
target: ".el-main",
text: "拼命加载中...",
spinner: "el-icon-loading",
lock: true,
background: "rgba(255,255,255,0.4)",
};
const loadingInstance = this.$loading(options);
this.axios
.post(
"***",
qs.stringify({
name: this.q,
page: this.listQuery.page,
}),
{
cancelToken: this.source.token,
}
)
.then((res) => {
this.tableData = res.data.data;
this.$nextTick(() => {
// 以服务的方式调用的 Loading 需要异步关闭
loadingInstance.close();
});
})
.catch((thrown) => {
// 如果请求被取消则进入该方法判断
if (axios.isCancel(thrown)) {
console.log("Request canceled", thrown.message);
this.$nextTick(() => {
// 以服务的方式调用的 Loading 需要异步关闭
loadingInstance.close();
});
} else {
// handle error
}
});
},
在离开页面的同时取消请求,关闭loading动画。
感悟
此次为了追求用户体验感更好,为此也走了不少的弯路,但我觉得还是很有意义的。同时也学到了不少新东西,如怎么取消一个请求等。还是很有收获的。