Concis组件库封装——Pagination分页器

简介: Concis组件库封装——Pagination分页器组件封装

您好,如果喜欢我的文章,可以关注我的公众号「量子前端」,将不定期关注推送前端好文~

分页器组件,文档页面如下:
在这里插入图片描述
在这里插入图片描述
组件封装代码如下:

import React, {
   
    useState, useEffect, FC, useMemo, memo } from 'react';
import {
   
    EllipsisOutlined, LeftOutlined, RightOutlined, DownOutlined } from '@ant-design/icons';
import {
   
    Select } from '..';
import style from './index.module.less'

interface PaginationProps {
   
   
    /**
     * @description 总数据条数
     * @default 0
     */
    total: number
    /**
     * @description 显示每页条数Select
     * @default false
     */
    showSizeChanger?: Boolean
    /**
     * @description 每页条数配置
     * @default 每页10条数据
     */
    pageSizeOptions?: Array<number>
    /**
     * @description 改变页码后的回调
     * @default {}
     */
    showJumpInput?: Boolean
    /**
     * @description 显示跳转页面输入框
     * @default false
     */
    changePageCallback: Function
}
const Pagination: FC<PaginationProps> = (props) => {
   
   
    const {
   
    changePageCallback, total, pageSizeOptions, showJumpInput, showSizeChanger } = props

    const [nowIndex, setNowIndex] = useState<number>(1);
    const [pageRenderArray, setPageRenderArray] = useState<Array<number>>([]);
    const [sizePage, setSizePage] = useState<number>(pageSizeOptions ? pageSizeOptions[0] : 10)
    const [showSizeOptions, setShowSizeOptions] = useState(false);

    const totalPage = useMemo(() => {
   
   
        setNowIndex(1)
        if (Math.ceil(total / sizePage) > 6) {
   
   
            setPageRenderArray([2, 3, 4, 5, 6])
        } else {
   
   
            if (Math.ceil(total / sizePage) > 2) {
   
   
                const array = new Array(Math.ceil(total / sizePage) as number - 2).fill(0);
                array.forEach((item, index) => {
   
   
                    array[index] = index + 2;
                })
                setPageRenderArray(array)
            } else {
   
   
                setPageRenderArray([])
            }
        }
        return Math.ceil(total / sizePage)
    }, [total, sizePage])
    useEffect(() => {
   
   
        console.log(typeof nowIndex)
    }, [nowIndex])

    //点击改页码
    const changePage = (pageNum: number) => {
   
   
        return () => {
   
   
            //小型分页器
            if (totalPage <= 6) {
   
   
                changePageCallback(pageNum)
                return setNowIndex(pageNum)
            }
            if (pageNum > 4 && pageNum <= totalPage - 4) {
   
   
                setPageRenderArray([pageNum - 2, pageNum - 1, pageNum, pageNum + 1, pageNum + 2])
            }
            //页码为1的情况
            if (pageNum <= 4) {
   
   
                setPageRenderArray([2, 3, 4, 5, 6])
            }
            //页码到倒数第四页内的情况
            if (pageNum > totalPage - 4) {
   
   
                setPageRenderArray([totalPage - 5, totalPage - 4, totalPage - 3, totalPage - 2, totalPage - 1])
            }
            setNowIndex(pageNum)
            changePageCallback(pageNum)
        }
    }
    //向前翻一页
    const prevPage = () => {
   
   
        if (nowIndex === 1) {
   
   
            return;
        }
        setNowIndex(nowIndex - 1);
        if (totalPage > 6) {
   
   
            if (nowIndex > totalPage - 3) {
   
   
                return
            } else if (nowIndex > 4) {
   
   
                setPageRenderArray(pageRenderArray.map(item => {
   
   
                    return item - 1;
                }))
            } else if (nowIndex - 5 <= 4) {
   
          //开头几页翻页的情况,回到第一页
                setPageRenderArray([2, 3, 4, 5, 6])
            }
        }
        changePageCallback(nowIndex - 1);
    }
    //向后翻一页
    const nextPage = () => {
   
   

        if (nowIndex === totalPage) {
   
   
            return;
        }
        setNowIndex(nowIndex + 1);
        if (totalPage > 6) {
   
   
            if (nowIndex + 5 > totalPage) {
   
   
                setPageRenderArray([totalPage - 5, totalPage - 4, totalPage - 3, totalPage - 2, totalPage - 1])
            }
            else if (nowIndex < 4) {
   
   
                return
            } else if (nowIndex + 5 < totalPage) {
   
   
                setPageRenderArray(pageRenderArray.map(item => {
   
   
                    return item + 1;
                }))
            }
        }
        changePageCallback(nowIndex + 1)
    }
    //向前翻五页
    const prevFivePage = () => {
   
   
        var updateIndex: number = 0;
        if (nowIndex - 5 <= 4) {
   
          //开头几页翻页的情况,回到第一页
            setPageRenderArray([2, 3, 4, 5, 6])
            updateIndex = nowIndex - 5 <= 1 ? 1 : nowIndex - 5
        }
        else if (nowIndex + 5 > totalPage) {
   
   
            setPageRenderArray([nowIndex - 7, nowIndex - 6, nowIndex - 5, nowIndex - 4, nowIndex - 3])
            updateIndex = nowIndex - 5;
        }
        else if (nowIndex - 5 > 4) {
   
         //中间翻页的情况
            setPageRenderArray(pageRenderArray.map(item => {
   
   
                return item - 5;
            }))
            updateIndex = nowIndex - 5;
        }
        setNowIndex(updateIndex);
        changePageCallback(updateIndex);
    }
    //向后翻五页
    const nextFivePage = () => {
   
   
        var updateIndex: number = 0;
        if (nowIndex + 7 >= totalPage) {
   
   
            setPageRenderArray([totalPage - 5, totalPage - 4, totalPage - 3, totalPage - 2, totalPage - 1]);
            updateIndex = nowIndex + 5 > totalPage ? totalPage : nowIndex + 5;
        }
        else if (nowIndex - 5 < 0) {
   
   
            setPageRenderArray([nowIndex + 3, nowIndex + 4, nowIndex + 5, nowIndex + 6, nowIndex + 7])
            updateIndex = nowIndex + 5;
        }
        else if (nowIndex + 5 < totalPage) {
   
   
            setPageRenderArray(pageRenderArray.map(item => {
   
   
                return item + 5;
            }))
            updateIndex = nowIndex + 5;
        }
        setNowIndex(updateIndex)
        changePageCallback(updateIndex)
    }
    //跳页
    const jumpPageNum = (e: any) => {
   
   
        if (e.keyCode === 13) {
   
   
            const jumpPage = Number(e.target.value);
            if (jumpPage > totalPage || jumpPage < 0 || isNaN(jumpPage)) {
   
          //超出页码范围,不挑
                return e.target.value = '';
            }
            if (jumpPage > 6 && jumpPage < totalPage - 6) {
   
   
                setPageRenderArray([jumpPage - 2, jumpPage - 1, jumpPage, jumpPage + 1, jumpPage + 2]);
            } else if (jumpPage - 5 < 0) {
   
   
                setPageRenderArray([2, 3, 4, 5, 6]);
            } else if (jumpPage + 5 > totalPage) {
   
   
                setPageRenderArray([totalPage - 5, totalPage - 4, totalPage - 3, totalPage - 2, totalPage - 1])
            }
            setNowIndex(jumpPage);
            changePageCallback(jumpPage)
            e.target.value = '';
        }
    }
    //select回调
    const handleSelectCallback = (pageSize: number) => {
   
   
        setSizePage(pageSize);
    }

    return (
        <div className={
   
   style.pagination}>
            <div className={
   
   nowIndex === 1 ? `${style.prev} ${style.disabled}` : `${
     
     style.prev}`} onClick={
   
   prevPage}>
                <LeftOutlined />
            </div>
            <div className={
   
   nowIndex === 1 ? `${style.actived} ${style.numberBox}` : `${
     
     style.numberBox}`} onClick={
   
   changePage(1)}>
                1
            </div>
            {
   
   
                nowIndex > 4 && totalPage > 6
                &&
                <div className={
   
   style.numberBox} onClick={
   
   prevFivePage}><EllipsisOutlined /></div>
            }

            {
   
   (totalPage <= 4 && pageRenderArray.length >= 1)
                &&
                pageRenderArray.map(index => {
   
   
                    return (
                        <div
                            className={
   
   nowIndex === index + 2 ? `${style.actived} ${style.numberBox}` : `${
     
     style.numberBox}`}
                            key={
   
   index}
                            onClick={
   
   changePage(index + 2)}>
                            {
   
   index + 2}
                        </div>
                    )
                })}
            {
   
   
                totalPage > 4
                &&
                pageRenderArray.map((item, index) => {
   
   
                    {
   
   
                        return (
                            <div
                                className={
   
   nowIndex === item
                                    ?
                                    `${style.actived} ${style.numberBox}`
                                    :
                                    `${
     
     style.numberBox}`}
                                key={
   
   index}
                                onClick={
   
   changePage(item)}>
                                {
   
   item}
                            </div>
                        )
                    }

                })
            }
            {
   
   
                totalPage - nowIndex >= 4 && totalPage > 6
                &&
                <div
                    className={
   
   style.numberBox}
                    onClick={
   
   nextFivePage}><EllipsisOutlined /></div>
            }
            {
   
   
                totalPage > 1
                &&
                <div
                    className={
   
   nowIndex === totalPage
                        ?
                        `${style.actived} ${style.numberBox}`
                        :
                        `${
     
     style.numberBox}`}
                    onClick={
   
   changePage(totalPage)}>
                    {
   
   totalPage}
                </div>
            }
            <div className={
   
   nowIndex === totalPage || totalPage <= 1
                ?
                `${style.next} ${style.disabled}`
                :
                `${
     
     style.next}`}
                onClick={
   
   nextPage}>
                <RightOutlined />
            </div>
            {
   
   /* {
                Array.isArray(pageSizeOptions) && showSizeChanger
                &&
                <div className={style.pageSizeSelect} onClick={() => setShowSizeOptions(!showSizeOptions)}>
                    <>
                        <span className={style.size}>{sizePage} 条/页</span>
                        <DownOutlined />

                    </>
                    {
                        showSizeOptions
                        &&
                        <div className={style.options}>
                            {
                                pageSizeOptions.map(s => {
                                    return (
                                        <div key={s as number} className={style.option} onClick={() => setSizePage(s as number)}>
                                            {s} 条/页
                                        </div>
                                    )
                                })
                            }
                        </div>
                    }
                </div>
            } */}
            {
   
   
                Array.isArray(pageSizeOptions) && showSizeChanger
                &&
                <Select 
                option={
   
   pageSizeOptions.map(item => {
   
   
                    return (
                        {
   
   
                            label: `${
     
     item} 条/页`,
                            value: item
                        }
                    )
                })}
                width={
   
   100}
                handleSelectCallback={
   
   handleSelectCallback}/>
            }
            {
   
   
                showJumpInput
                &&
                <div className={
   
   style.jumpBox}>
                    <span>跳至</span>
                    <input type="text" className={
   
   style.jump} onKeyUp={
   
   jumpPageNum}></input>
                    <span>页</span>
                </div>
            }
        </div>
    )
}
export default memo(Pagination);
目录
相关文章
|
JSON 测试技术 数据格式
5 JMeter断言-Jmeter响应中出现乱码时
5 JMeter断言-Jmeter响应中出现乱码时
459 0
|
7月前
|
人工智能 安全 Java
超越Linux之后:OpenClaw登顶GitHub,但开发者真正需要怎样的AI编程工具?
2026年3月,AI助手OpenClaw登顶GitHub活跃度榜首,标志AI从“聊天”迈向“实干”。而飞算JavaAI专业版另辟蹊径——专注Java生态,以全量语义分析、自定义规范、框架深度适配,直击老项目接手难、代码水土不服、版本兼容差三大痛点,做开发者真正可信的“技术搭档”。(239字)
|
8月前
|
人工智能 数据可视化 网络安全
零基础必看:2026年OpenClaw(Clawdbot)阿里云一键部署教程+接入iMessage指南
在AI自动化工具爆发的2026年,OpenClaw(原Clawdbot、Moltbot)凭借“自然语言指令+多场景任务自动执行”的核心优势,成为新手小白追捧的“专属数字员工”——它无需专业编程基础,就能实现文件管理、联网搜索、多平台协同等多样化功能,而阿里云轻量服务器推出的OpenClaw一键部署方案,更是彻底打破了新手的入门壁垒,预置专属镜像、自动化配置环境,全程可视化操作,哪怕你完全不懂技术、不懂服务器,跟着步骤也能15-20分钟完成部署,部署后还能快速接入iMessage,实现手机、Mac端随时随地操控AI,解锁高效办公与便捷生活新方式。
650 2
|
10月前
|
消息中间件 缓存 NoSQL
【Redis进阶】不止是缓存!Redis的5种核心数据结构与实战场景全解析
本文深入浅出地解析了Redis五大核心数据结构:String、Hash、List、Set和ZSet,结合图解与实战场景,涵盖缓存、计数器、分布式锁、购物车、消息队列、排行榜等典型应用,助你摆脱“只会SET/GET”的困境,真正发挥Redis的高性能潜力。
|
JavaScript 前端开发
JS几种拼接字符串的方法
JS几种拼接字符串的方法
544 1
|
人工智能 开发者
钉钉AI助理接入DeepSeek,深度思考,能力更强
钉钉AI助理全面接入DeepSeek系列模型,包括R1、V3和R1-qwen32b蒸馏版。用户可在钉钉上创建AI助理时选择这些模型,并使用全新模板一键创建、发布和使用基于DeepSeek模型的AI助理。PC端和移动端均提供了简便的操作步骤来创建和发布AI助理,无需复杂配置即可实现深度思考和联网查询功能。此次更新旨在提升工作效率,提供更丰富的选择和更智能的体验。
1783 14
|
SQL 关系型数据库 MySQL
GORM V2 安装和连接 MySQL
GORM V2 安装和连接 MySQL
1416 0
|
数据可视化 开发者 Python
Python GUI开发:Tkinter与PyQt的实战应用与对比分析
【10月更文挑战第26天】本文介绍了Python中两种常用的GUI工具包——Tkinter和PyQt。Tkinter内置于Python标准库,适合初学者快速上手,提供基本的GUI组件和方法。PyQt基于Qt库,功能强大且灵活,适用于创建复杂的GUI应用程序。通过实战示例和对比分析,帮助开发者选择合适的工具包以满足项目需求。
1452 7
|
存储 编解码 算法
视频为什么可以被压缩?帧内压缩与帧间压缩有何区别?视频编码中的CBR、VBR、CRF...是什么?
视频压缩基于冗余,包括空间冗余、时间冗余、视觉冗余和编码冗余。帧内压缩利用空间相关性,帧间压缩利用时间相关性。视频编码中的码率控制方法有CBR(固定码率)、VBR(动态码率)、CRF(固定码率系数)、CQP(固定质量参数)、CVBR(约束可变码率)和ABR(平均码率),各有优缺点,适用于不同的场景。
|
机器学习/深度学习 TensorFlow 语音技术
手把手教你用Python打造一个语音合成系统
手把手教你用Python打造一个语音合成系统
616 0
手把手教你用Python打造一个语音合成系统