前言
继上一次发现el-pagination在删除的时候pageNum不更新的问题。这次又发现了,切换分页条数,会出现两次请求。网上有很多解决方案,我就不多说了,我就简单记一下为啥会出现两次请求的问题
一、问题展示
这是点击切换分页条数,发出的请求次数,以及pageNum。上图展示的是第一次请求pageNum为2,第二次请求pageNum为1,也就是正确的请求参数。两次接口分别为一次handleSizeChange,一次handleCurrentChange
// 第一种方案
// 计算totalPage,如果大于pageNum,才执行接口请求。
// 这就说明pageNum没有超出应有的页码,接口会正常返回数据,不会为空。
// 且el-pagination组件内部不会进行pageNum的数字修正,也就不会执行handleCurrentChange。
// 而pageNum超出应有的页码,例如只有1页,但是pageNum为2的话,则不进行请求。
// el-pagination组件内部会进行pageNum的数字修正,执行handleCurrentChange。下面的源码会解析
handleSizeChange(val) {
const totalPage = Math.ceil(this.totalSize / val);
if (this.pageNum <= totalPage) {
this.getTable();
}
},
// 第二种方案
// 计算totalPage,如果小于pageNum,修正currentPage,再才执行接口请求。
// 这就说明pageNum超出应有的页码,例如只有1页,但是pageNum为2的话,则需要将pageNum(currentPage)修正。
// 且el-pagination组件内部不会进行pageNum的数字修正,也就不会执行handleCurrentChange。
handleSizeChange(val) {
const totalPage = Math.ceil(this.totalSize / val);
if (this.pageNum > totalPage) {
this.currentPage = totalPage < 1 ? 1 : totalPage;
}
this.getTable();
},
二、源码展示
代码如下:
Size:{
methods: {
// 1、切换分页条数之后就会执行这个方法,会执行handleSizeChange
handleChange: function handleChange(val) {
if (val !== this.$parent.internalPageSize) {
console.log('Size:methods:handleChange');
// 这里会触发computed
this.$parent.internalPageSize = val = parseInt(val, 10);
this.$parent.userChangePageSize = true;
this.$parent.$emit('update:pageSize', val);
this.$parent.$emit('size-change', val);
}
}
}
}
methods: {
// 4、会执行这个方法,oldPage=2, newVal=1。这里就会执行handleCurrentChange
emitChange: function emitChange() {
var _this2 = this;
this.$nextTick(function () {
if (_this2.internalCurrentPage !== _this2.lastEmittedPage || _this2.userChangePageSize) {
console.log('methods:emitChange');
_this2.$emit('current-change', _this2.internalCurrentPage);
_this2.lastEmittedPage = _this2.internalCurrentPage;
_this2.userChangePageSize = false;
}
});
}
}
computed: {
// 2、切换分页条数之后就会执行这个方法,会触发watch
internalPageCount: function internalPageCount() {
console.log('computed:internalPageCount', Math.max(1, Math.ceil(this.total / this.internalPageSize)), Math.max(1, this.pageCount));
if (typeof this.total === 'number') {
return Math.max(1, Math.ceil(this.total / this.internalPageSize));
} else if (typeof this.pageCount === 'number') {
return Math.max(1, this.pageCount);
}
return null;
}
},
watch: {
internalPageCount: function internalPageCount(newVal) {
/* istanbul ignore if */
var oldPage = this.internalCurrentPage;
// 3、会执行这个方法,oldPage=2, newVal=1。这里就会执行emitChange
// 这里就是如果更新了pageNum(currentNum),那就说明oldPage和newVal一样,就不会触发emitChange,也就不会执行handleCurrentChange
console.log('watch:internalPageCount', oldPage, newVal);
if (newVal > 0 && oldPage === 0) {
this.internalCurrentPage = 1;
} else if (oldPage > newVal) {
this.internalCurrentPage = newVal === 0 ? 1 : newVal;
this.userChangePageSize && this.emitChange();
}
this.userChangePageSize = false;
}
}
下面展示一下elementui的打印结果:
1、这是错误的调用两次请求的,handleSizeChange和handleCurrentChange
2、这是第一种解决方案
这里是pageNum=2,totalPage=1,是不会执行getTable方法的,if没有进去
3、第二种解决方案