Pagination分页

101 阅读2分钟

本人已参与「新人创作礼」活动,一起开启掘金创作之路

不知不觉,摸鱼已经有半年了,发现自己少有自定义一些通用组件,刚刚好需求需要。

技术栈是react加TypeScript

需求如下:

固定显示5个按钮,当页数超过5页的时候,除了显示对应页数按钮,同时显示首页和尾页,并且可以设置每页的条数

import { useState, useMemo } from 'react';
import './jj.css'
interface Props {
  total: number//总数据条数
  defaultPageSize: number//默认的每页条数
  pageSizeOptions?: number[]//指定每页可以显示多少条
  onChange: (e:E) => void//回调出当前的页数和每页的条数
}
interface E{
  size:number
  index:number
}
export const Pagination = (props: Props) => {
  const { total, defaultPageSize, pageSizeOptions, onChange } = props
  const [numberr, setNumberr] = useState<number>(1)
  const [defaultt, setDefault] = useState<number>(0)
  const Button = (I: number) => <button key={I}
    className={numberr == I + 1 ? 'bb' : ''}
    onClick={() => {
      setNumberr(I + 1);
      onChange({size:defaultt!=0?defaultt:defaultPageSize,index:I+1})//回调出当前页数和条数
    }}>
    {I + 1}
  </button>
  const yeis = useMemo(() => {//通过同数据数/每页的条数,得出总页数,当每页的条数改变的时候,重新计算
    return defaultt != 0 ? new Array(Math.ceil(total / defaultt)).fill(1) :
      new Array(Math.ceil(total / defaultPageSize)).fill(1)
  }, [total, defaultt])
  return (
    <>
      <div>
        {
          (numberr > 3 && yeis.length > 5) ?//当当前页大于3,并且总页数大于5的时候,显示首页
            <>
              <button onClick={() => { 
                setNumberr(1)
                onChange({size:defaultt!=0?defaultt:defaultPageSize,index:1})
              }}>1</button>
              <span>.....</span>
            </> : <></>
        }
        {yeis.map((T: number, I: number) => {//判断当前页是否在前3页或者后3页,确保当前页可以显示在中间
          if (numberr <= 3 && I < 5) {
            return Button(I)
          } else if (numberr > 3 && I > numberr - 4 && I < numberr + 2 && numberr < yeis.length - 1) {
            return Button(I)
          } else if (numberr + 3 > yeis.length && I + 6 > yeis.length) {
            return Button(I)
          }
        }
        )}
        {
          (yeis.length - 2 > numberr && yeis.length > 5) ?//当当前页是后3页,并且总页数大于5的时候,显示首页
            <>
              <span>.....</span>
              <button onClick={() => {
                setNumberr(yeis.length)
                onChange({size:defaultt!=0?defaultt:defaultPageSize,index:yeis.length})
              }}>
                {yeis.length}
              </button>
            </> : <></>}
        {pageSizeOptions ?
          <select onChange={(e) =>{//改变当前页的条数
            setDefault(Number(e.target.value))
            onChange({size:Number(e.target.value),index:numberr})
          }}>
            {pageSizeOptions.map((T: number, I: number) =>
              <option key={T} value={T}>{T}</option>)}
          </select> : <></>
        }
      </div>
    </>
  );
};

//调用的方式
 <Pagination total={255} defaultPageSize={5} pageSizeOptions={[10,20,50,100]} onChange={(e)=>{console.log(e)}}/>


效果如下

1667986089096-c771297c-6629-42a2-8815-e32d34fa9b1e.png

1667986238304-ad4fdff0-ab80-46de-88f4-3e7bfe9b7e01.png

1667986260507-9dfd48cc-e8ed-4c09-b199-c08b8c8b0282.png

当然,还可以添加跳转到指定的页面,但是,没这个需求嘛233333333

摸鱼摸鱼