废话很少说,咱们先来分析一下一个分页组件的结构,实际这个分析很关键,比真正的逻辑判断重要的多,下面先看图: javascript
咱们能够看到此分页组件:vue
《上一页》《下一页》 2 个 : 2
《首页》《尾页》 2 个 : 2
省略号 2 个 : 2
当前页 1 个 : 1
当前页左右各2个 :2 * 2
复制代码
因此这个分页组件一共是由 2 + 2 + 2 + 1 + 2 * 2 = 11 个 元素构成。记住这个数,给这个变量起名字叫baseCount,待会要着重用它。分析到这逻辑实际已经完成74%了,是否是惊呆了?可是不要着急,咱们继续分析一下分页组件须要哪些参数:java
参数我已经标注好了,你们应该能知道这几个参数的意思,我就不解释了。好,说回刚才的那个baseCount,咱们看看baseCount和组件变量有啥关系,发现只跟around有关系:baseCount = 2 + 2 + 2 + 1 + 2 * around。到这完成75%。react
咱们已经获得一个很简单的值:baseCount,可是它有什么用呢?实际上它很关键,咱们可以用这个值来判断分页组件何时出现省略号。好比上面图中这个组件,除掉两边的上一页、下一页两个按钮,中间部分一共有11 - 2 = 9个元素,也就是说当分页的总数total <= 9的时候,是不须要省略号的,由于位置够用,都能显示彻底。 数组
先来看个小问题:1,...,3,4,5。这其中的省略号表明着啥?表明2吧。但是省略号这里直接用2不就好了吗,自己2也就占一个位置,用省略号岂不是画蛇添足(实际不少分页组件实现过程当中省略号最少只代替了一个元素,也并无大碍)。因此省略号的正确用法应该如这样:1,...,4,5,6(省略号表明2,3)或者6,7,8,...,12(省略号表明9,10,11)。所以我的认为省略号的做用就是最少代替2个元素。ui
接下来看分页组件省略号出现的位置,通常会有三种状况,最开始的例子是一种,就是两边都出现省略号,还有两种以下:spa
一、只出如今后面 3d
出现省略号的前提条件是total > baseCount -2,由于此时可用位置不够显示彻底全部页数,须要用省略号来代替。code
a.先肯定只出如今后面的状况(前面即将出现省略号),首先肯定何时前面恰好出现省略号?根据刚刚得出的省略号的做用,也就是说它最少代替两个元素。因此咱们就取这个最小值2,此时是在前面刚刚出现省略号,省略号表明的越多则说明cur越日后。cdn
这个时候cur的位置应该是在:首页(1) + 省略号最小值(2) + cur左边的值around(2)的下一个,即cur = 1 + 2 + around + 1,标记一下叫startPosition。所以当cur < startPosition时前面是不会出现省略号的,仅在后面出现省略号,因此就肯定了省略号开始出现时的位置:startPosition = 1 + 2 + around + 1。
b.一样的逻辑,咱们还能够得出只在前面出现,后面不会出现省略号的一个临界位置:endPosition = 尾页(total) - 省略号最小值(2) - cur 右边的值(2) - 1。即cur > endPosition时只在前面出现省略号。
ok,逻辑分析已经完成了95%,还剩下一种两边都出现省略号的状况,咱们不用分析了,除去刚才的两种状况就是它了,也就是当 startPosition <= cur && cur <= endPosition。
分析完省略号的位置,其余的就超级简单了,还记得刚才那个很重要的baseCount吗,仍是用它。 刚才获得的baseCount是11,由于上一页和下一页一直都会存在。咱们能够先不用管这俩,只看中间实际用到的9个位置。
咱们能够看到当省略号只出如今后面时,可用位置的最后两个必定是 ... 和 total。因此这个省略号前面的还剩下9 - 2 = 7个位置,给这个变量也取个名字叫surplus,就从1开始显示到surplus就行了。也是一样的道理,当省略号只出如今前面时,前面的两个位置必定是 1 和 ...。因此后面各个位置就是从 (total-surplus) 一直到 total 了。
还有就是两边都出现省略号,前面两个确定是 1 和 ...,后面两个又确定是 ... 和 total。那么中间的就是cur以及其左右两边的相邻的around个。
当有省略号出现时,这种逻辑保证了分页组件总共须要的元素的个数是固定的,且只跟around有关,around取值建议为2或者3。到此,分页逻辑分析就所有结束了,下面是一个生成分页组件对应数组的方法,供各位小伙伴参考:
/** * * @param {Number} total * @param {Number} cur * @param {Numbre} around */
const makePage = (total,cur,around) => {
let result = [];
let baseCount = around * 2 + 1 + 2 + 2 + 2; //总共元素个数
let surplus = baseCount - 4; //只出现一个省略号 剩余元素个数
let startPosition = 1 + 2 + around + 1;//前面出现省略号的临界点
let endPosition = total - 2 - around - 1;//后面出现省略号的临界点
if(total <= baseCount - 2){ //所有显示 不出现省略号
result = Array.from({length: total}, (v, i) => i + 1);
}else{ //须要出现省略号
if(cur < startPosition){ //1.只有后面出现省略号
result = [...Array.from({length: surplus}, (v, i) => i + 1),"...",total]
}else if(cur > endPosition) { //2.只有前边出现省略号
result = [1,'...',...Array.from({length: surplus}, (v, i) => total - surplus + i + 1)]
}else{ //3.两边都有省略号
result = [1,'...',...Array.from({length: around * 2 + 1}, (v, i) => cur - around + i),'...',total]
}
}
return result
}
makePage(8,2,2);//[1, 2, 3, 4, 5, 6, 7, 8]
makePage(20,3,2);//[1, 2, 3, 4, 5, 6, 7, "...", 20]
makePage(20,10,2);//[1, "...", 8, 9, 10, 11, 12, "...", 20]
makePage(20,19,2);//[1, "...", 14, 15, 16, 17, 18, 19, 20]
复制代码
能够根据这个方法生成的数组来肯定分页组件显示哪些内容,用react、vue或者源生js均可以,逻辑都是同样的,还能够根据需求加上跳转到第几页、是否显示首页尾页等相关功能和逻辑。