前两天在开发一个管理后台项目时, 遇到了一个问题,后端接口返回特别慢,由于该接口调用的是第三方API,无法通过后端去处理。此时想到用loading动画,但随之而来也产生了不少问题, 在此记录一下以方便大家能够遇到此类问题可以借鉴。
处理方案 在表格内添加loading <el-table v-loading="loading" :data="tableData" border tooltip-effect="dark" :row-class-name="tableRowClassName" > ... </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动画。
感悟此次为了追求用户体验感更好,为此也走了不少的弯路,但我觉得还是很有意义的。同时也学到了不少新东西,如怎么取消一个请求等。还是很有收获的。