美文网首页前端成长记
react通用自定义分页组件(防百度等,只显示十页码)

react通用自定义分页组件(防百度等,只显示十页码)

作者: TurnHug | 来源:发表于2022-01-28 14:36 被阅读0次
项目需求背景介绍:

1.react+ant
2.由于列表数据过多,不希望显示所有分页(防止用户一上来就点击最后一页,数据量计算大请求缓慢)
3.期望的分页组件是少于十页正常显示,多余十页则只显示相邻的十个页码,类似于百度的分页效果,如图:


image.png
image.png

翻阅了很多ui库,都没有这样的分页组件,只能自己实现了

自定义实现:

自己加了首页和尾页的快速切换和页码快速跳转和总条数,根据需要可自行设置对应的参数true或false

/* eslint-disable */
// react通用分页组件(最多只显示10页)
import React,{memo, useState,useEffect} from 'react'
// 引用的图标
import {LeftOutlined, RightOutlined, DoubleLeftOutlined, DoubleRightOutlined} from '@ant-design/icons'
import './page.scss'
function CustomPage (props) {
    // page当前页码,number
    // size每页条数,number
    // total数据总数,number
    // changePage分页切换
    // showJump是否显示快速跳转,true/false
    // showTotal是否显示总数
    // showEnds是否显示首页尾页快速切换
    const { page=1, size=10, total=1, changePage, showJump=true, showTotal=true, showEnds=true} = props
    const [pageArr, setPageArr] = useState([])//页面显示的页码数组
    const [jumpPage, setJumpPage] = useState('')//快速跳转页码
    
    // 初始化分页
    function initializationPage () {
        const totalPage = Math.ceil(total/size)//总页数
        let result = [];//盛放当前显示的所有页码的数组
        if(totalPage < 11){//总页数小于11页的情况
            for(let i = 0;i<totalPage;i++){
                result.push(i+1);
            }
        }else if(page > 5 && (totalPage - page) > 3){//当前页大于5且总页数减当前页大于3
            result = [page-5,page-4,page-3,page-2,page-1,page,page+1,page+2,page+3,page+4]
        }else if(page > 5 && totalPage - page < 4){//当前页大于5且总页数减当前页小于4
            result = [totalPage-9,totalPage-8,totalPage-7,totalPage-6,totalPage-5,totalPage-4,totalPage-3,totalPage-2,totalPage-1,totalPage]
        }else if(page<6 && totalPage > 9){//当前页小于6且总页数大于9
            for(let i = 0;i<10;i++){
                result.push(i+1);
            }
        }
        setPageArr(result)
    }
    //快速跳转页码回车事件
    function handleEnterKey (e) {
        e.persist()
        const value = e.target.value
        if(e.nativeEvent.keyCode === 13){
            if (value =='') {
                return
            }
            changePage(parseInt(value))
            setJumpPage('')
        }
    }
    // 快速跳转框值发生变化
    function changeJumpPage (e) {
        e.persist()
        const value = e.target.value
        const totalPage = Math.ceil(total/size)
        if (value != '') {
            if (parseInt(value) > 0) {
                // 如果输入的页码大于总页数,则默认最后一页
                if (parseInt(value)>totalPage) {
                    setJumpPage(parseInt(totalPage))
                } else {
                    setJumpPage(parseInt(value))
                }
            }
        } else {
            setJumpPage('')
        }
    }
    useEffect(()=> {
        initializationPage()
    },[page,total,size])
    return <div className='custom-page flex-start-center'>
            {showTotal && 
                <div className='total'>
                    <span>Total</span>
                    <span className='total-num'>{total}</span>
                    <span>items</span>
                </div>
            }
            {showEnds && 
                <div className={`first-page pre-page change-page ${page==1 ? 'click-none':''}`} onClick={()=>changePage(1)}><DoubleLeftOutlined/></div>
            }
            <div className={`pre-page change-page ${page==1 ? 'click-none':''}`} onClick={()=>changePage(page-1)}><LeftOutlined/></div>
            <ul className='pagination-ul flex-start-center'>
                {pageArr.map(i=> <li onClick={()=>changePage(i)} key={i} className={page==i ? 'selected-act' : ''}>{i}</li>)}
            </ul>
            <div className={`next-page change-page ${page==Math.ceil(total/size) ? 'click-none':''}`} onClick={()=>changePage(page+1)}><RightOutlined/></div>
            {showEnds && 
                <div className={`last-page pre-page change-page ${page==Math.ceil(total/size) ? 'click-none':''}`} onClick={()=>changePage(Math.ceil(total/size))}><DoubleRightOutlined/></div>
            }
            {showJump && 
                <div className='jump-page'>
                    <span>go to</span>
                    <input type="number" value={jumpPage} onChange={changeJumpPage} onKeyPress={handleEnterKey} />
                    <span>page</span>
                </div>
            }
        </div>
}
export default memo(CustomPage)
.custom-page {
    width: fit-content;
    .selected-act{
        color: $main-color-drak-green;
        border-color: $main-color-drak-green;
    }
    .change-page{
        font-size: 16px;
        color: #000;
        height: 32px;
        border: 1px solid #d9d9d9;
        border-radius: 4px;
        line-height: 32px;
        min-width: 32px;
        text-align: center;
        cursor: pointer;
        &:hover {
            color: $main-color-drak-green;
            border-color: $main-color-drak-green;
        }
    }
    .click-none {
        opacity: 0.3;
        pointer-events: none;
    }
    .pre-page {
        margin-right: 8px;
    }
    .last-page {
        margin-left: 8px;
    }
    ul {
        margin: 0;
    }
    li{
        list-style: none;
        height: 32px;
        line-height: 32px;
        min-width: 32px;
        text-align: center;
        margin-right: 8px;
        border: 1px solid #d9d9d9;
        border-radius: 4px;
        outline: 0;
        cursor: pointer;
        &:hover {
            color: $main-color-drak-green;
            border-color: $main-color-drak-green;
        }
    }
    .total {
        margin-right: 15px;
        .total-num {
            margin: 0 8px;
        }
    }
    .jump-page {
        margin-left: 15px;
        input {
            -moz-appearance:textfield;
            height: 32px;
            width: 50px;
            border: 1px solid #d9d9d9;
            border-radius: 4px;
            outline:none;
            margin: 0 10px;
            text-indent: 10px;
            &:focus {
                border-color: $main-color-drak-green;
            }
        }
        input::-webkit-outer-spin-button,
        input::-webkit-inner-spin-button {
            -webkit-appearance: none;
            appearance: none;
            margin: 0;
        }
        input[type="number"] {
            -moz-appearance: textfield;
        }
    }
}
//使用
//xxx为组件路径
import CustomPage from 'xxx'
function onChangePage (page) {
//写自己的分页切换逻辑
}
...
<CustomPage changePage={onChangePage} />
附上默认配置的效果图
image.png
image.png
image.png

相关文章

网友评论

    本文标题:react通用自定义分页组件(防百度等,只显示十页码)

    本文链接:https://www.haomeiwen.com/subject/mpqtkrtx.html