
我们并非只有一次生命;
如果我们能够阅读,
就能够随心所欲地拥有多次生命和多种活法。
————塞缪尔·早川
说明
最近做项目过程中,由于网络不佳或者请求数据数据过大,进入页面时,会出现空白,用户体验不好,所以加入加入一个数据未出现之前的加载效果。
具体实现步骤是:
- 接口定义,在axios的get与post方法中通过headers添加自定义头部信息来传递值
- 使用axios的拦截器获取到自定义头部数据后做出相关处理
- 配置element-ui Loading 加载组件
接口定义
参数说明
-
condition
{}||自定义hash对象,必传
-
headerConfig
| 参数 | 类型 | 作用 | 默认值 |
|---|---|---|---|
| showLoading | boolean | 在发起axios请求时,是否显示loading动画 | false |
| loadingTarget | string | loading动画要挂载的dom选择器 | body节点 |
get方法
get类型接口
var getFunc = function(condition, headerConfig) {
return axios.get(`/v1/items/source/search?action=getimages`, {
params: condition,
headers: headerConfig
});
};
页面调用
var headerConfig = {
showLoading: true,
loadingTarget: "#box-nodata"
};
var condition = {
searchTerms: this.q,
from: this.fromPage,
size: this.pageSize
};
getFunc(condition, headerConfig)
.then(res => {
//后台传过来的total为string类型,需要转换成number类型
this.totalNum = parseInt(res.total);
this.itemList = res.result;
})
.catch(err => {
this.$message({
showClose: true,
type: "error",
message: `数据加载出错。原因:${err.message}`
});
});
post方法
post类型接口
var postFunc = function(condition, headerConfig) {
return axios.post(`/v1/search/item`, condition, {
headers: headerConfig
});
};
注意在post方法中,condition与headers的赋值方式
页面调用
var headerConfig = {
showLoading: true,
loadingTarget: "#box-nodata"
};
var condition = {
searchTerms: this.q,
from: this.fromPage,
size: this.pageSize
};
postFunc(condition, headerConfig)
.then(res => {
//后台传过来的total为string类型,需要转换成number类型
this.totalNum = parseInt(res.total);
this.itemList = res.result;
})
.catch(err => {
this.$message({
showClose: true,
type: "error",
message: `数据加载出错。原因:${err.message}`
});
});
在get与post方法中,condition是作为查询参数,而headerConfig作为我们通过axios请求时额外传递的参数
axios拦截器处理
通过axios拦截器,我们在请求与获取数据后做加载的相关处理,在发起请求时我们先显示正在加载条,当获得数据后关闭加载条,代码如下:
import axios from "axios";
import { Loading } from "element-ui";
import { response_handle } from "./response_handle";
// loading对象
let loading;
// 请求合并只出现一次loading
// 当前正在请求的数量
let needLoadingRequestCount = 0;
/* 请求拦截器 */
axios.interceptors.request.use(
config => {
// 如果当前请求要显示Loading
if (config.headers.showLoading)
showLoading(config.headers.loadingTarget);
return config;
},
err => {
hideLoading();
return Promise.resolve(err);
}
);
/* 响应拦截器 */
axios.interceptors.response.use(
response => {
hideLoading();
/* 这里对返回的response做了简单的处理,
就不需要对每个接口在做处理了 */
return response_handle(response);
},
error => {
//判断当前请求是否设置了不显示Loading(不显示自然无需隐藏)
hideLoading();
return Promise.reject(error);
}
);
/* 显示loading */
function showLoading(target) {
// 后面这个判断很重要,因为关闭时加了抖动,此时loading对象可能还存在,
// 但needLoadingRequestCount已经变成0.避免这种情况下会重新创建个loading
if (needLoadingRequestCount === 0 && !loading) {
loading = Loading.service({
lock: true,
text: "数据加载中,请耐心等候...",
background: "rgba(255, 255, 255 ,1)",
target: target || "body"
});
}
needLoadingRequestCount++;
}
/* 隐藏loading */
function hideLoading() {
if (needLoadingRequestCount <= 0) return;
needLoadingRequestCount--;
if (needLoadingRequestCount === 0 && loading) {
loading.close();
loading = null;
}
}
调用element-ui的Loading 加载组件服务
其中Loading插件用了element-ui现成的组件,以服务的方式调用。
引入 Loading 服务:
import { Loading } from 'element-ui';
在需要调用时:
Loading.service(options);
其中 options 参数为 Loading 的配置项。