前端UI组件设计系统【免费下载链接】element-reactElement UI项目地址https://gitcode.com/gh_mirrors/el/element-react点击查看免费下载当数据量超出单页可承载范围时分页是 React 管理后台与数据列表中几乎必用的交互模式。本文基于 element-reactElement UI 的 React 版本仓库中的官方文档site/docs/en-US/pagination.md展开完整覆盖 Pagination 组件的layout布局系统、全部属性与事件并结合src/pagination/目录下的源码实现讲清页码裁剪算法、当前页钳制逻辑、每页条数联动等底层原理帮助你不仅会用组件还能预判其边界行为。Pagination 组件概览element-react 将 Pagination 作为具名导出提供入口在 src/index.jsexport { default as Pagination } from ./pagination;而 src/pagination/index.js 直接转发默认导出真正的实现全部集中在 src/pagination/Pagination.jsx 与页码列表子组件 src/pagination/Pager.jsx 两个文件中。组件的 TypeScript 声明位于 typings/index.d.ts官方文档页则通过 site/pages/pagination/index.jsx 读取本目录对应的 Markdown 渲染而成。组件的核心设计只有一个思想用一条layout字符串描述要显示哪些子模块顺序即排列顺序。从 Pagination.jsx 的render()可以看到layout被按逗号切分后逐项映射到内部的TEMPLATE_MAP// src/pagination/Pagination.jsx节选 const components layout.split(,).map(item item.trim()); const TEMPLATE_MAP { prev: Pre .../, jumper: Jumper .../, pager: Pager .../, next: Next .../, sizes: Sizes .../, total: Total .../ }; components.forEach(compo { if (compo ! -) { children.push(TEMPLATE_MAP[compo]); } });也就是说layout中每一项要么命中TEMPLATE_MAP渲染对应子组件要么被忽略——这正是后续所有附加模块示例能够任意组合的基础。基础用法用 layout 控制布局官方文档给出两个典型场景页数较少total{50}默认pageSize为 10共 5 页与页数超过 7 页total{1000}共 100 页render() { return ( div classNamefirst div classNameblock span classNamedemonstrationWhen you have few pages/span Pagination layoutprev, pager, next total{50}/ /div div classNameblock span classNamedemonstrationWhen you have more than 7 pages/span Pagination layoutprev, pager, next total{1000}/ /div /div ) }layout支持的元素逗号分隔顺序即显示顺序元素含义prev上一页按钮next下一页按钮pager页码列表jumper跳页输入框total总条目数文本sizes每页条数选择器文档正文中也写作size实际 layout 中须写sizes-布局分隔符文档约定该符号之后的元素靠右显示这里有两个值得注意的实现细节空 layout 直接不渲染。render()中有if (!layout) return null;即不传layout的组件是空的-在源码中只被跳过。从 Pagination.jsx 的结构看forEach循环遇到-时不 push 任何组件同时className中el-pagination__rightwrapper被固定为false见 L305-L309。因此该 React 版本中-不产生独立 DOM右对齐效果由组件样式层承担使用时遵循文档语义书写即可。组件的默认布局在 Pagination.defaultProps 中定义Pagination.defaultProps { small: false, pageSize: 10, currentPage: 1, layout: prev, pager, next, jumper, -, total, pageSizes: [10, 20, 30, 40, 50, 100] };这与文档 Attributes 表中layout的默认值一致。小型分页small空间有限时使用小型分页只需把small设为truerender() { return Pagination layoutprev, pager, next total{50} small{true}/ }源码中该属性直接映射为 BEM 修饰类见 Pagination.jsxconst className this.classNames({ el-pagination: true, el-pagination__rightwrapper: false, el-pagination--small: this.props.small });即small为true时根节点附加el-pagination--small类尺寸变化完全由样式表驱动JS 逻辑不受影响。附加功能total、sizes、jumper官方文档More elements一节给出了完整用例分别演示显示总数、调整每页条数、跳页以及全功能组合render() { return ( div classNamelast div classNameblock span classNamedemonstrationTotal item count/span Pagination layouttotal, prev, pager, next total{1000}/ /div div classNameblock span classNamedemonstrationChange page size/span Pagination layoutsizes, prev, pager, next total{1000} pageSizes{[100, 200, 300, 400]} pageSize{1000}/ /div div classNameblock span classNamedemonstrationJump to/span Pagination layoutprev, pager, next, jumper total{1000} pageSize{100} currentPage{5}/ /div div classNameblock span classNamedemonstrationAll combined/span Pagination layouttotal, sizes, prev, pager, next, jumper total{400} pageSizes{[100, 200, 300, 400]} pageSize{100} currentPage{5}/ /div /div ) }下面逐个说明这三个模块在源码中的行为。total总条数文本Total是一个极轻量的展示组件Pagination.jsx L58-L64const Total props { return typeof props.total number ? span classNameel-pagination__total {locale.t(el.pagination.total, { total: props.total })} /span : span /; };只有total是数字时才会渲染文案否则输出空span/。文案本身走国际化例如英文包 src/locale/lang/en.js 中为Total {total}中文包 src/locale/lang/zh-CN.js 中为共 {total} 条——即total模块的显示文案随组件全局 locale 变化无需额外配置。sizes每页条数选择器Sizes组件Pagination.jsx L31-L56内部复用 Select 组件把pageSizes数组逐项渲染为选项{this.props.pageSizes.map((item, idx) { return ( Select.Option key{idx} value{item} label{item locale.t(el.pagination.pagesize)} / ); })}因此文档中pageSizes{[100, 200, 300, 400]}会得到100 /page、200 /page……四个下拉选项中文环境下为100 条/页。初始化时内部每页条数的取值逻辑在构造函数中Pagination.jsx L119-L127let internalPageSize 0; if (layout.split(,).indexOf(sizes) -1 Array.isArray(pageSizes)) { internalPageSize pageSizes.indexOf(pageSize) -1 ? pageSize : pageSizes[0]; } else { internalPageSize pageSize; }可以推断两条规则只有 layout 含sizes时才会校验pageSize是否属于pageSizes若不属于则静默回退为pageSizes[0]。这解释了为什么在Change page size示例中显式传入pageSize{1000}后实际生效的每页条数是pageSizes的第一项100该示例的意图是演示回退行为。jumper跳页输入框Jumper组件Pagination.jsx L66-L97渲染一个typenumber的输入框关键属性由组件内部计算min{1}、max{this.props.internalPageCount}——输入范围被限制在合法页码区间默认值显示当前页internalCurrentPage触发时机有两个onBlur失焦或按下回车e.keyCode 13。用户提交的页码最终汇入jumperToPage()L249-L264与pre()/next()走同一条校验 → setState → 比较旧值 → 回调事件的处理链。Attributes 属性表以下属性表完整继承自官方文档site/docs/en-US/pagination.md默认值与 Pagination.defaultProps 逐一核对一致AttributeDescriptionTypeAccepted ValuesDefaultsmallwhether to use small paginationboolean—falsepageSizeitem count of each pagenumber—10totaltotal item countnumber——pageCounttotal page count. Set eithertotalorpage-countand pages will be displayed; if you needpageSizes,totalis requirednumber——currentPagecurrent page numbernumber—1layoutlayout of Pagination, elements separated with a commastringsizes,prev,pager,next,jumper,-,total,slotprev, pager, next, jumper, -, totalpageSizesoptions of item count per pagenumber[]—[10, 20, 30, 40, 50, 100]两个需要留意的点total与pageCount二选一。页码总数的计算函数internalPageCount()Pagination.jsx L237-L247明确了优先级internalPageCount(): ?number { if (this.state) { if (typeof this.state.total number) { return Math.ceil(this.state.total / this.state.internalPageSize); } else if (typeof this.state.pageCount number) { return this.state.pageCount; } } return null; }total优先且页数由total / internalPageSize向上取整得到因此需要支持sizes动态切换每页条数时必须传total否则切换pageSize后无法重新推算页数。两者都未传时函数返回nullpager与jumper的max等依赖项都会按无有效页数处理。slot的实际情况。文档 Accepted Values 中列出了slot但从源码结构看当前版本的TEMPLATE_MAP只包含prev / jumper / pager / next / sizes / total六项slot在forEach中会 push 到undefinedReact 会忽略不渲染。使用slot语法时不会报错但也不会有可见输出属于文档预留而源码未落地的能力。Events 事件表Event NameDescriptionParametersonSizeChangetriggers whenpage-sizechangesthe newpage-sizeonCurrentChangetriggers whencurrent-pagechangesthe newcurrent-pageReact 版本采用驼峰事件属性与 Vue 版的size-change/current-change对应。从源码看两个事件都有去重保护onSizeChange仅在选中的值与内部internalPageSize不同才触发触发前还会把当前页用新页大小重新钳制一遍L281-L300onCurrentChangepre()、next()、jumperToPage()、handleCurrentChange()四条路径全部是先setState在回调里比较oldPage ! this.state.internalCurrentPage不同才调用onCurrentChange。也就是说点击当前页、或在第一页点上一页这类无效操作不会派发事件。事件签名可在 typings/index.d.ts 中确认interface PaginationProps extends ElementReactLibs.ComponentProps{} { pageSize?: number small?: boolean total?: number pageCount?: number currentPage?: number layout?: string pageSizes?: number[] onCurrentChange?(currentPage?: number): void onSizeChange?(size?: number): void }页码列表pager的裁剪算法当页数超过 7 时基础用法中total{1000}、pageSize10即 100 页的场景中间页码会被省略号替代。这一行为的实现全部在 src/pagination/Pager.jsx 中1. 窗口计算。getPages()以pagerCount 7为窗口宽度根据当前页位置决定省略号显示L67-L116if (pageCount pagerCount) { if (currentPage pagerCount - 2) { showPrevMore true; // 当前页靠后 → 头部出现 more } if (currentPage pageCount - 2) { showNextMore true; // 当前页靠前 → 尾部出现 more } }随后分四种情况生成中间页码靠后时从pageCount - 5开始补齐尾部靠前时固定显示第 2~6 页中间位置则以当前页为中心、offset Math.floor(pagerCount / 2) - 1为半径取连续 7 页。首尾页1与pageCount在render()中单独渲染L125-L180始终常驻。2. 省略号的快速跳转。more 标记不是纯装饰点击btn-quickprev/btn-quicknext会在当前页基础上快速前进或后退 5 页L44-L49if (target.className.indexOf(more) ! -1) { if (target.className.indexOf(quickprev) ! -1) { newPage currentPage - 5; } else if (target.className.indexOf(quicknext) ! -1) { newPage currentPage 5; } }且所有点击路径页码点击、快速跳转最终都经过同一处边界修正newPage 1归 1newPage pageCount归pageCount只有与当前页不同时才调用this.props.onChange(newPage)向上冒泡。悬停时省略号图标还会从el-icon-more切换为双箭头el-icon-d-arrow-left/right提示可点击L138-L143。当前页的钳制逻辑getValidCurrentPage所有页码变更入口——翻页按钮、点击页码、跳页输入框、外部 props 更新——最终都会经过getValidCurrentPage()Pagination.jsx L212-L235getValidCurrentPage(value: string | number): number { value parseInt(value, 10); let internalPageCount this.internalPageCount(); let resetValue; if (!internalPageCount) { if (isNaN(value) || value 1) resetValue 1; } else { if (value 1) { resetValue 1; } else if (value internalPageCount) { resetValue internalPageCount; } } if (resetValue undefined isNaN(value)) { resetValue 1; } else if (resetValue 0) { resetValue 1; } return resetValue undefined ? value : resetValue; }其语义可以概括为未配置有效页数时非法值一律落到第 1 页配置了页数时值被夹紧到[1, internalPageCount]区间。这带来两个实际影响外部受控更新currentPage时componentWillReceiveProps中检测到 props 变化后调用L139-L176若新值超出范围会被自动修正组件内部永远保持合法状态切换pageSize导致总页数缩小时例如每页 400 条改回 100 条时onSizeChange会主动对当前页做一次getValidCurrentPage重算避免停留在不存在的页码上。而prev/next按钮的禁用态则由两个内联组件直接判断Pre在internalCurrentPage 1时加disabledL9-L16Next在internalCurrentPage internalPageCount || internalPageCount 0时禁用L18-L29——注意0 页时下一页按钮也会被禁用避免空数据下的无效点击。典型集成模式把属性、事件与源码行为串起来一个受控的完整用法通常长这样import { Pagination } from element-react; class DataList extends Component { state { currentPage: 1, pageSize: 20, total: 0 }; handleCurrentChange (currentPage) { this.setState({ currentPage }, () this.fetchData()); }; handleSizeChange (size) { // 组件内部已按新 size 钳制过当前页 this.setState({ pageSize: size, currentPage: 1 }, () this.fetchData()); }; fetchData() { const { currentPage, pageSize } this.state; // 向服务端请求第 currentPage 页、每页 pageSize 条的数据 } render() { const { currentPage, pageSize, total } this.state; return ( Pagination layouttotal, sizes, prev, pager, next, jumper total{total} pageSizes{[10, 20, 30, 40]} pageSize{pageSize} currentPage{currentPage} onCurrentChange{this.handleCurrentChange} onSizeChange{this.handleSizeChange} / ); } }要点使用sizes时必须传total而非pageCount以便组件重算页数回调里拿到的是已经过钳制的合法值可直接用于发起请求。小结element-react 的 Pagination 组件以一条layout字符串为骨架把prev、pager、next、sizes、jumper、total六个子模块自由拼装配合small、pageSizes等属性覆盖大多数列表分页场景onCurrentChange/onSizeChange两个事件携带合法值驱动数据层。深入 src/pagination/Pagination.jsx 与 src/pagination/Pager.jsx 后可以确认页码窗口固定为 7、省略号支持 ±5 快速跳转、所有页码变更统一经过getValidCurrentPage()钳制、total的优先级高于pageCount、事件均带值未变化不触发的保护。这些行为边界在自定义封装或排查分页异常时尤其有价值。相关参考文件文档site/docs/en-US/pagination.md中文版见 site/docs/zh-CN/pagination.md实现src/pagination/Pagination.jsx、src/pagination/Pager.jsx类型typings/index.d.ts文案src/locale/lang/zh-CN.js、src/locale/lang/en.js赞分享前端UI组件设计系统【免费下载链接】element-reactElement UI项目地址https://gitcode.com/gh_mirrors/el/element-react点击查看免费下载相关推荐用 MAS 激活 Windows 和 Office四种方式怎么选、三种跑法怎么做用 MAS 激活 Windows 和 Office四种方式怎么选、三种跑法怎么做 重装完系统桌面右下角又出现激活 Windows的水印打开 Word操作系统Mac Mouse Fix 完整指南把普通鼠标变成 Mac 上最顺手的输入设备Mac Mouse Fix 完整指南把普通鼠标变成 Mac 上最顺手的输入设备 花二十块买来的鼠标接上 Mac滚轮方向反直觉侧键点了没反应指针还快得没脾桌面应用系统编程rsuite Pagination 高级定制用 layout 属性自由编排分页组件布局rsuite Pagination 高级定制用 layout 属性自由编排分页组件布局 分页Pagination组件用于辅助长列表分批加载数据、让用户快速前端UI组件创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考