分页器的折叠 用生成器实现

分页器的难点在于: 页数超过最大页码数时要折叠,而折叠怎么实现呢?

生成器生成分页器的页码序列,包含折叠按钮

期望: genPager(总页数=9,当前页=5,最大页码数=7) --> prev 1 ... 3 4 5 6 7 ... 9 next

使用场景: 分页器组件中 v-for="item of computedPager"

currentPage 可v-model双向绑定,这样页码序列可自动跟新

实现

/* 
/* 
生成 页码和折叠块的序列, 折叠块包含中间数,以便点击折叠块跳到中间页数
num:总页数
currentPage:当前页
pagerCount: 分页器的最大页码数(限制为奇数)
*/
function* genPager(num, currentPage, pagerCount = 7) {
    // 没有折叠,直接生成从1开始数组
    if(num<=pagerCount){ 
        yield* Array.from({length:num},(_,i)=>i+1) 
        return
    }
    
    /* 1. 先找临界条件 什么情况下左/右边有剩余  */
    let l_remain = currentPage - Math.ceil(pagerCount / 2) > 0
    let r_remain = num + 1 - Math.ceil(pagerCount / 2) > currentPage

    /* 2. 再找中间的页码, 两边都有折叠时为: ... currentPage-2 currentPage-1 currentPage currentPage+1  currentPage+2 ...*/
    let arr = Array.from({ length: pagerCount - 2 }, (_, i) => {
        /* 只有一边有剩余 时 中间数组 "靠岸"了,就和和当前页没有关系*/
        if (!l_remain && r_remain) return i + 2
        if (l_remain && !r_remain)
            return i + num - Math.ceil(pagerCount / 2) - 1
        return i + currentPage - Math.ceil(pagerCount / 2) + 2  
    })
    /* 3. 生成序列 */
    if (l_remain) yield {button:'prev'} // 表示此处应有"上一页"按钮
    yield 1
    if (l_remain) yield { middle: Math.ceil(arr[0] / 2) }
    yield* arr
    if (r_remain) yield { middle: Math.ceil((num + arr[arr.length - 1]) / 2) }
    yield num
    if (r_remain) yield {button:'next'} // 表示此处应有"下一页"按钮
}
/* 测试 */
//console.log([...genPager(5, 5,5)])   //[ 1, 2, 3, 4, 5 ]
// for(let i=1;i<=10;i++){

//     console.log([...genPager(10, i)]) // 1 * 3 4 5 6 7 * 10
// }

posted on 2021-12-12 15:48  ShawSpring  阅读(83)  评论(0编辑  收藏  举报

导航