React-页码组件

1.首先封装一个页码组件

1)PaginationField.jsx:

复制代码
import {useState,useEffect} from 'react';
import Pagination from 'react-bootstrap/Pagination';
//import Form from 'react-bootstrap/Form';
import Dropdown  from 'react-bootstrap/Dropdown';
import styles from './Pagination.module.scss';

const PaginationField = ({ totalItems, pageSize, currentPage, onPageChange , onPageSizeChange}) => {
  // 计算总页数
  const totalPages = Math.ceil(totalItems / pageSize);
  // 创建一个数组用于生成分页按钮
  const [pages, setpages] = useState(null);
  const [allPages, setallPages] = useState(null);

  useEffect(
    () => {
      let data=[]
      let allPage=[]
      if(totalPages <= 10){
          for (let i = 1; i <= totalPages; i++) {
            data.push(i);
          }
      }else{
        if (currentPage <= 6) {
          data=[1,2,3,4,5,6,7,8,9,10]
        }else{
          if (currentPage<totalPages-4) {
            for (let i = currentPage-5; i <= currentPage+4; i++) {
              data.push(i);
            }
          }else{
            for (let i = totalPages-9; i <= totalPages; i++) {
              data.push(i);
            }
          }
        }
      }
      for (let i = 1; i <= totalPages; i++) {
        allPage.push(i);
      }
      setpages(data)
      setallPages(allPage)
    },
    [currentPage,totalPages]
  );

  // 改变当前页码的函数
  const handlePageChange = (page) => {
    page=Number(page)
    onPageChange(page);
  };

  // 改变每页的行数的函数
  const handlePageSizeChange = (pageSize) => {
    pageSize=Number(pageSize)
    onPageSizeChange(pageSize);
    onPageChange(1);
  };

  return (
    <div className={styles.container}>
      <div className={styles.flex}>
        Page
        {/* <Form.Select className={styles.selectStyle} onChange={e=>handlePageChange(e.target.value)} value={currentPage}>
          {allPages?allPages.map((page) => (<option key={page} value={page}>{page}</option>)):null}
        </Form.Select> */}
        <Dropdown onSelect={handlePageChange} drop="up">
          <Dropdown.Toggle className={styles.selectStyle}>{currentPage}</Dropdown.Toggle>
          <Dropdown.Menu className={styles.dropdownMenu}>
            {allPages?allPages.map((page) => (<Dropdown.Item key={page} eventKey={page}>{page}</Dropdown.Item>)):null}
          </Dropdown.Menu>
         </Dropdown>
        of {totalPages}
      </div>
      <Pagination className={styles.myPagination}>
        <Pagination.First onClick={() => handlePageChange(1)}/>
        <Pagination.Prev onClick={() => handlePageChange(currentPage-1)} disabled={currentPage == 1}/>
        {pages?pages.map((page) => (
          <Pagination.Item 
            key={page} 
            onClick={() => handlePageChange(page)} 
            active={currentPage == page}   
            linkStyle={currentPage == page?{ 
              backgroundColor: '#a89a72', 
              borderColor: '#a89a72'
            }:undefined}>{page}
          </Pagination.Item>
        )):null}
        <Pagination.Next onClick={() => handlePageChange(currentPage+1)} disabled={currentPage == totalPages}/>
        <Pagination.Last onClick={() => handlePageChange(totalPages)}/>
      </Pagination>
      <div className={styles.flex}>
        Items 
        <Dropdown onSelect={handlePageSizeChange} drop="up">
          <Dropdown.Toggle className={styles.selectStyle}>{pageSize}</Dropdown.Toggle>
          <Dropdown.Menu className={styles.dropdownMenu}>
            <Dropdown.Item eventKey="5">5</Dropdown.Item>
            <Dropdown.Item eventKey="10">10</Dropdown.Item>
            <Dropdown.Item eventKey="20">20</Dropdown.Item>
            <Dropdown.Item eventKey="25">25</Dropdown.Item>
            <Dropdown.Item eventKey="50">50</Dropdown.Item>
            <Dropdown.Item eventKey="100">100</Dropdown.Item>
          </Dropdown.Menu>
         </Dropdown>
      </div>
    </div>
  );
};

export default PaginationField;

2)Pagination.module.scss:

复制代码
.container {
  display: flex;
  justify-content: space-between;
}

.flex {
  display:flex
}

.selectStyle{
  width:60px;
  height:25px;
  border-color: #a89a72;
  cursor: pointer;
  padding: .25rem .75rem;
  font-size: .85rem;
  line-height: 1.3;
  margin:0px 5px;
  color: #a89a72;
  background-color: white;
  // option{
  //   color: #a89a72;
  // }

  // option:checked {
  //   background-color: #a89a72; /* 理论上改变选中项的背景色,但实际效果有限 */
  //   color:white;
  // }
}

.selectStyle:focus{
  box-shadow: 0 0 5px #a89a72; /* 阴影 */
  border-color: #a89a72;
}

.dropdownMenu {
  max-height: 400px; /* 设置你想要的固定高度 */
  overflow-y: auto; /* 启用垂直滚动条,如果内容超出高度 */
  font-size:.85rem;
}


.myPagination{
  li a{
    background: transparent;
    border: 1px solid #a89a72;
    color: #a89a72;
    //transition: background-color 0.3s ease;
  }
  li a:hover{
    color: #a89a72; 
    box-shadow: 0 0 5px #a89a72; /* 阴影 */
  }
  li a:active{
    background-color: #a89a72;
    color:white;
  }
  li a:focus{
    background-color: #a89a72;
    color:white;
  }
}

3)index.js

复制代码
export { default } from './PaginationField.jsx';

2.在主页面中调用这个页码组件

复制代码
import PaginationField from 'components/PaginationField';
import {useState} from 'react';

function PageAppReportView() {
  const [currentPage, setCurrentPage] = useState(1); // 当前页码初始化为1
  const [pageSize, setPageSize]= useState(5); // 每页显示的项目数
  const [totalItems] = useState(300);//总项目数
  const handlePageChange = (page) => {
    setCurrentPage(page);
  };
  const handlePageSizeChange = (pageSize) => {
    setPageSize(pageSize);
  };
  return (
    <>
      <PaginationField 
                totalItems={totalItems} 
                pageSize={pageSize} 
                currentPage={currentPage} 
                onPageChange={handlePageChange} 
                onPageSizeChange={handlePageSizeChange} 
              />
    </>
  );
}

PageAppReportView.getLayout = (page) => <GeneralLayout containerClassName={styles.container}>{page}</GeneralLayout>;

export default PageAppReportView;
相关推荐
一 乐35 分钟前
婚纱摄影网站|基于ssm + vue婚纱摄影网站系统(源码+数据库+文档)
前端·javascript·数据库·vue.js·spring boot·后端
C_心欲无痕1 小时前
ts - tsconfig.json配置讲解
linux·前端·ubuntu·typescript·json
清沫1 小时前
Claude Skills:Agent 能力扩展的新范式
前端·ai编程
yinuo2 小时前
前端跨页面通信终极指南:方案拆解、对比分析
前端
yinuo2 小时前
前端跨页面通讯终极指南⑨:IndexedDB 用法全解析
前端
xkxnq3 小时前
第二阶段:Vue 组件化开发(第 16天)
前端·javascript·vue.js
烛阴3 小时前
拒绝配置地狱!5 分钟搭建 Three.js + Parcel 完美开发环境
前端·webgl·three.js
Van_Moonlight3 小时前
RN for OpenHarmony 实战 TodoList 项目:空状态占位图
javascript·开源·harmonyos
xkxnq3 小时前
第一阶段:Vue 基础入门(第 15天)
前端·javascript·vue.js
anyup4 小时前
2026第一站:分享我在高德大赛现场学到的技术、产品与心得
前端·架构·harmonyos