- 前端
- UI组件
- 设计系统
【免费下载链接】ant-design-blazor
基于 Ant Design 与 Blazor 的前端组件库。让开发者解放生产力,实现更大价值。
分页组件是长列表数据展示的标配,而"每页显示多少条"往往是用户最常调整的交互之一。本篇技术指南以 ant-design-blazor 仓库中 Pagination 的 Changer 示例文档(官方描述为"改变每页显示条目数 / Change pageSize")为骨架,完整讲解如何开启 PageSize 切换器、绑定尺寸变化回调、定制可选页大小,并深入 Pagination.razor.cs 与 PaginationOptions.razor.cs 源码,弄清"切换每页条数"在底层到底发生了什么。读完本文,你将能独立为任何列表接入可配置的分页尺寸切换能力,并理解其默认行为边界。
一、功能定位:PageSize 切换器解决什么问题
当数据总量较大时,不同的用户对"一页看多少条"有不同诉求:运营人员希望每页 50 条快速浏览,开发人员调试时则可能希望每页 10 条精确定位。Pagination 组件的 PageSize 切换器(Ant Design 官方又称 sizeChanger / Changer)正是为此设计:
- 在分页条右侧提供一个下拉框,供用户选择每页显示的条目数;
- 切换后页码自动按新尺寸重新计算,并可通过回调通知业务层重新加载数据;
- 官方文档核心描述仅有一句:"改变每页显示条目数"(Change pageSize),对应仓库示例 Changer.razor。
在 ant-design-blazor 中,这一交互由三个关键参数组合完成:ShowSizeChanger(是否展示切换器)、PageSizeOptions(可选条目数集合)与OnShowSizeChange(切换回调),三者分别解决"显示不显示、能选哪些、变了怎么办"。
二、快速上手:完整示例代码
仓库中的官方示例位于 site/AntDesign.Docs/Demos/Components/Pagination/demo/Changer.razor,展示了基础用法与禁用态两种形态,完整代码如下:
<Pagination ShowSizeChanger OnShowSizeChange="OnShowSizeChange" DefaultCurrent="3" Total="500"/> <br/> <Pagination ShowSizeChanger OnShowSizeChange="OnShowSizeChange" DefaultCurrent="3" Total="500" Disabled/> @code { private void OnShowSizeChange(PaginationEventArgs args) { var(current, pageSize) = args; Console.WriteLine($"{current}, {pageSize}"); } }逐行拆解这个示例:
| 参数 | 取值 | 作用 |
|---|---|---|
ShowSizeChanger | 布尔开关,示例置为true | 显式开启"每页条数"下拉切换器 |
OnShowSizeChange | 事件回调 | 用户切换每页条数后触发,参数为PaginationEventArgs |
DefaultCurrent | "3" | 初始页号,示例直接定位到第 3 页 |
Total | "500" | 数据总数,分页器据此计算总页数 |
Disabled | 布尔开关,第二个示例置为true | 整组分页(含切换器)进入禁用态 |
事件处理代码中有两个值得注意的细节:
PaginationEventArgs解构:var(current, pageSize) = args;利用了PaginationEventArgs实现的Deconstruct(out int page, out int pageSize)方法(见 PaginationEventArgs.cs),可以一行同时取出"切换后的当前页码"与"新的每页条数";- 回调不负责翻页:示例只是把
current, pageSize打印到控制台。实际业务中,你通常应在此回调里根据新的pageSize重新向服务端请求数据。
第二个Disabled示例则演示了禁用态:整个分页器(页码按钮、切换器、快速跳转输入框)都会变为灰色不可交互,适合数据加载中或权限受限的场景。
三、核心参数详解
结合 Pagination 官方 API 文档 与源码实现,与"改变每页条数"直接相关的参数如下:
| 参数 | 说明 | 类型 | 默认值 |
|---|---|---|---|
ShowSizeChanger | 是否展示PageSize切换器;未显式设置时,当Total大于TotalBoundaryShowSizeChanger则默认为true | bool | 见说明 |
PageSizeOptions | 指定每页可以显示多少条的下拉选项 | int[] | [10, 20, 50, 100] |
OnShowSizeChange | PageSize 变化时的回调,参数是变化后的页码及每页条数 | EventCallback<PaginationEventArgs> | - |
OnChange | 页码改变的回调(切换 PageSize 触发页码校正时也会触发) | EventCallback<PaginationEventArgs> | - |
TotalBoundaryShowSizeChanger | 当Total大于该值时,ShowSizeChanger默认为true | int | 50 |
DefaultPageSize | 默认的每页条数 | int | 10 |
PageSize | 受控的每页条数 | int | - |
Disabled | 禁用分页(含切换器) | bool | false |
Total | 数据总数 | int | 0 |
关于ShowSizeChanger的默认值,有一个"隐藏规则"
API 表格中ShowSizeChanger的默认值写作-,但这并不等于"默认不显示"。查看 Pagination.razor.cs 中的实现:
private bool GetShowSizeChanger() { if (_showSizeChanger.HasValue) { return _showSizeChanger.Value; } return Total > TotalBoundaryShowSizeChanger; }即:当你不显式声明ShowSizeChanger时,组件会自动判断——只要Total超过TotalBoundaryShowSizeChanger(默认 50),切换器就会自动出现。因此在示例中即使不写ShowSizeChanger,Total="500"也会展示切换器;而如果Total很小(比如几十条),则默认不显示,避免干扰。TotalBoundaryShowSizeChanger就是用来调整这一自动出现阈值的。
PageSizeOptions的自动合并行为
PageSizeOptions默认值为[10, 20, 50, 100](定义见 PaginationOptions.razor.cs 的DefaultPageSizeOptions)。但如果你的DefaultPageSize/PageSize不在该集合中(例如设成 30),切换器下拉并不会漏掉当前值——GetPageSizeOptions() 会自动把当前PageSize追加进去并按升序排列:
private int[] GetPageSizeOptions() { PageSizeOptions ??= DefaultPageSizeOptions; if (PageSizeOptions.Any(option => option == PageSize)) { return PageSizeOptions; } return PageSizeOptions.Concat(new[] { PageSize }).OrderBy(e => e).ToArray(); }下拉中每个选项的文案由BuildOptionText生成:$"{value} {Locale.ItemsPerPage}",即本地化拼接。在简体中文语言包 components/locales/zh-CN.json 中items_per_page为条/页,所以选项显示为10 条/页、20 条/页等;英文语言包则显示为10 / page(见 components/locales/en-US.json)。
四、源码解析:切换每页条数时底层发生了什么
这一节沿着源码调用链,逐步还原"用户在下拉框选中新条数"到"页面状态更新、回调触发"的完整过程。
第 1 步:切换器由Select组件渲染
Pagination渲染结构中的最后一部分是 PaginationOptions.razor,当ChangeSize委托存在时,它内部直接复用了组件库的Select来渲染下拉:
changeSelect = @<Select TItem="int" TItemValue="int" Disabled="@Disabled" Style="width: auto" Size="@(IsSmall ? InputSize.Small : InputSize.Default)" Class="@($"{prefixCls}-size-changer")" DefaultValue="@(PageSize > 0 ? PageSize : pageSizeOptions[0])" Value="@PageSize" BoundaryAdjustMode="@TriggerBoundaryAdjustMode.InView" OnSelectedItemChanged="@ChangePaginationSize"> <SelectOptions> @foreach(var opt in pageSizeOptions) { <SelectOption TItem="int" TItemValue="int" Label="@BuildOptionText(opt)" Value="@opt" /> } </SelectOptions> </Select>;注意此处Select的OnSelectedItemChanged指向ChangePaginationSize,同时PageSize参数被双向传递,因此切换器始终高亮显示当前生效的每页条数;BoundaryAdjustMode="@TriggerBoundaryAdjustMode.InView"保证下拉菜单弹出时不会被视口边缘裁切。
第 2 步:选择变化触发回调链
用户选中新数值后,先进入 PaginationOptions.razor.cs 的ChangePaginationSize:
private async Task ChangePaginationSize(int value) { if (PageSize == value) { return; } PageSize = value; if (ChangeSize.HasDelegate) { await ChangeSize.InvokeAsync(value); } }它会去重(相同值直接忽略)、更新内部PageSize,然后通过ChangeSize委托把新值回传给Pagination组件(在 Pagination.razor 中该委托绑定为ChangePageSize)。
第 3 步:ChangePageSize校正页码并触发业务回调
核心逻辑在 Pagination.razor.cs 的ChangePageSize:
private async Task ChangePageSize(int size) { var current = _current; var newCurrent = CalculatePage(size, _pageSize, Total); current = current > newCurrent ? newCurrent : current; // fix the issue: // Once 'total' is 0, 'current' in 'onShowSizeChange' is 0, which is not correct. if (newCurrent == 0) { current = _current; } PageSize = size; Current = current; if (OnShowSizeChange.HasDelegate) { await OnShowSizeChange.InvokeAsync(new(current, size)); } if (OnChange.HasDelegate) { await OnChange.InvokeAsync(new(current, size)); } }这里包含三个关键行为:
- 页码自动收缩:
CalculatePage按公式(total - 1) / size + 1计算新总页数(Pagination.razor.cs)。如果当前页号超过新的总页数(例如原来每页 10 条共 50 页、当前在第 48 页,切换到每页 100 条后只剩 5 页),组件会把当前页自动收缩到最后一页newCurrent,绝不会停留在"不存在的页码"上; - 边界容错:当
Total为 0 时newCurrent为 0,此时保留原current,避免向业务层回调错误的current = 0; - 双回调触发:切换每页条数不仅触发
OnShowSizeChange,同时也会触发OnChange(页码被校正时尤其如此)。因此业务上若只关心"数据重新加载",通常只需绑定OnChange;若想区分"用户主动切页"与"用户切换每页条数",则可用OnShowSizeChange单独感知。
第 4 步:事件参数的数据结构
回调统一携带 PaginationEventArgs,包含Page与PageSize两个属性,并支持解构到(int page, int pageSize)元组,方便var(current, pageSize) = args;这种写法。若使用ShowTotal展示数据范围,还会用到 PaginationTotalContext(含Total与Range,Range为(from, to)元组),可据此渲染"共 500 条 / 第 21-30 条"之类的信息。
五、实战建议与常见问题
结合源码行为,给出几条可直接落地的使用建议:
- 显式声明
ShowSizeChanger以消除歧义:虽然Total > 50时切换器会自动出现,但显式声明能让代码意图更清晰,也避免在Total边界变化时 UI 行为"自动漂移"。 - 让
PageSizeOptions覆盖你的默认每页条数:虽然源码会自动把当前PageSize并入下拉,但主动把默认值纳入PageSizeOptions(如PageSizeOptions="new[] { 10, 20, 30, 50, 100 }"配合DefaultPageSize="30")可以保持选项顺序稳定、符合产品预期。 - 注意双回调的联动:切换每页条数会同时触发
OnShowSizeChange与OnChange,避免在两者中重复发起两次数据请求;建议把数据加载逻辑收敛到OnChange,仅在需要额外埋点时使用OnShowSizeChange。 - 禁用态会整体覆盖:
Disabled会同时禁用页码、切换器和快速跳转输入框(在 PaginationOptions.razor 中Disabled参数被透传给Select和跳转输入框),适合加载态与只读态。 - 响应式与简单模式:
Responsive参数在源码注释中标记为 "Not implemented",当前不会自动根据屏幕宽度调整;若页面空间有限,可配合Simple简单分页模式使用(简单模式下不渲染尺寸切换器,见 Pagination.razor 的分支逻辑)。
六、延伸阅读
- 官方 Changer 示例及说明:site/AntDesign.Docs/Demos/Components/Pagination/demo/changer.md、Changer.razor
- Pagination 完整 API 与使用场景:site/AntDesign.Docs/Demos/Components/Pagination/doc/index.zh-CN.md
- 组件主实现:components/pagination/Pagination.razor、components/pagination/Pagination.razor.cs
- 切换器渲染与选项逻辑:components/pagination/PaginationOptions.razor、components/pagination/PaginationOptions.razor.cs
- 事件与上下文数据结构:components/pagination/PaginationEventArgs.cs、components/pagination/PaginationTotalContext.cs
- 切换器文案的本地化定义:components/locales/zh-CN.json、components/locales/en-US.json
- 前端
- UI组件
- 设计系统
【免费下载链接】ant-design-blazor
基于 Ant Design 与 Blazor 的前端组件库。让开发者解放生产力,实现更大价值。
相关推荐
Ant Design Pagination 每页条数切换器(showSizeChanger)完整实战指南
Ant Design Pagination 每页条数切换器(showSizeChanger)完整实战指南 导读 在管理后台与数据表格类页面中,用户经常需要在一页
前端UI组件设计系统沉浸式翻译扩展失效了?10 分钟定位并修复 immersive-translate 常见故障的完整指南
沉浸式翻译扩展失效了?10 分钟定位并修复 immersive translate 常见故障的完整指南 immersive translate(沉浸式翻译)安装
前端AI 应用Ant Design Blazor Carousel 渐显切换效果(Fade)实战与源码解析
Ant Design Blazor Carousel 渐显切换效果(Fade)实战与源码解析 导读 本文围绕 Ant Design Blazor 组件库中 Ca
UI组件前端
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考