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;
相关推荐
光影少年2 小时前
useMemo 和 React.memo区别
前端·react.js·前端框架
消失的旧时光-19432 小时前
Flutter 与 React/Vue 为什么思想一致?——声明式 UI 体系的深度对比(超清晰版)
vue.js·flutter·react.js
零一科技2 小时前
Vue3学习第三课: ref 与 reactive 选择指南
前端·vue.js
余杭子曰3 小时前
播放状态与播放序列的关系(999篇一线博客第107篇)
前端
e***U8204 小时前
前端路由懒加载实现,React.lazy与Suspense
前端·react.js·前端框架
诸葛亮的芭蕉扇4 小时前
抓图巡检-底图支持绘制
开发语言·前端·javascript
来碗盐焗星球4 小时前
yalc,yyds!
前端
熊猫比分站4 小时前
让电竞数据实时跳动:Spring Boot 后端 + Vue 前端的完美融合实践
前端·vue.js·spring boot
eason_fan4 小时前
ESLint报错无具体信息:大型代码合并中的内存与性能问题排查
前端