news 2026/10/11 21:47:03

Ant Design Blazor Pagination 分页 PageSize 切换器(Changer)实战指南与源码解析

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Ant Design Blazor Pagination 分页 PageSize 切换器(Changer)实战指南与源码解析
  • 前端
  • UI组件
  • 设计系统

【免费下载链接】ant-design-blazor

基于 Ant Design 与 Blazor 的前端组件库。让开发者解放生产力,实现更大价值。

项目地址:https://gitcode.com/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整组分页(含切换器)进入禁用态

事件处理代码中有两个值得注意的细节:

  1. PaginationEventArgs解构:var(current, pageSize) = args;利用了PaginationEventArgs实现的Deconstruct(out int page, out int pageSize)方法(见 PaginationEventArgs.cs),可以一行同时取出"切换后的当前页码"与"新的每页条数";
  2. 回调不负责翻页:示例只是把current, pageSize打印到控制台。实际业务中,你通常应在此回调里根据新的pageSize重新向服务端请求数据。

第二个Disabled示例则演示了禁用态:整个分页器(页码按钮、切换器、快速跳转输入框)都会变为灰色不可交互,适合数据加载中或权限受限的场景。

三、核心参数详解

结合 Pagination 官方 API 文档 与源码实现,与"改变每页条数"直接相关的参数如下:

参数说明类型默认值
ShowSizeChanger是否展示PageSize切换器;未显式设置时,当Total大于TotalBoundaryShowSizeChanger则默认为truebool见说明
PageSizeOptions指定每页可以显示多少条的下拉选项int[][10, 20, 50, 100]
OnShowSizeChangePageSize 变化时的回调,参数是变化后的页码及每页条数EventCallback<PaginationEventArgs>-
OnChange页码改变的回调(切换 PageSize 触发页码校正时也会触发)EventCallback<PaginationEventArgs>-
TotalBoundaryShowSizeChanger当Total大于该值时,ShowSizeChanger默认为trueint50
DefaultPageSize默认的每页条数int10
PageSize受控的每页条数int-
Disabled禁用分页(含切换器)boolfalse
Total数据总数int0

关于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)); } }

这里包含三个关键行为:

  1. 页码自动收缩:CalculatePage按公式(total - 1) / size + 1计算新总页数(Pagination.razor.cs)。如果当前页号超过新的总页数(例如原来每页 10 条共 50 页、当前在第 48 页,切换到每页 100 条后只剩 5 页),组件会把当前页自动收缩到最后一页newCurrent,绝不会停留在"不存在的页码"上;
  2. 边界容错:当Total为 0 时newCurrent为 0,此时保留原current,避免向业务层回调错误的current = 0;
  3. 双回调触发:切换每页条数不仅触发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 条"之类的信息。

五、实战建议与常见问题

结合源码行为,给出几条可直接落地的使用建议:

  1. 显式声明ShowSizeChanger以消除歧义:虽然Total > 50时切换器会自动出现,但显式声明能让代码意图更清晰,也避免在Total边界变化时 UI 行为"自动漂移"。
  2. 让PageSizeOptions覆盖你的默认每页条数:虽然源码会自动把当前PageSize并入下拉,但主动把默认值纳入PageSizeOptions(如PageSizeOptions="new[] { 10, 20, 30, 50, 100 }"配合DefaultPageSize="30")可以保持选项顺序稳定、符合产品预期。
  3. 注意双回调的联动:切换每页条数会同时触发OnShowSizeChange与OnChange,避免在两者中重复发起两次数据请求;建议把数据加载逻辑收敛到OnChange,仅在需要额外埋点时使用OnShowSizeChange。
  4. 禁用态会整体覆盖:Disabled会同时禁用页码、切换器和快速跳转输入框(在 PaginationOptions.razor 中Disabled参数被透传给Select和跳转输入框),适合加载态与只读态。
  5. 响应式与简单模式: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 的前端组件库。让开发者解放生产力,实现更大价值。

项目地址:https://gitcode.com/ant-design-blazor/ant-design-blazor
点击查看免费下载

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/11 21:46:38

ClickHouse 字典缓存(Dictionary)实战:利用内存哈希表加速维表翻译

在构建面向业务一线或外部客户的实时分析报表时&#xff0c;数据工程师经常面临一个极其普遍的性能两难&#xff1a; 在底层数仓事实表&#xff08;如 dwd_orders&#xff09;中&#xff0c;为了最大化存储压缩比与向量化扫描速度&#xff0c;我们通常只保存数值型的物理编码与…

作者头像 李华
网站建设 2026/10/11 21:46:26

工业刀具检测专用YOLO数据集与全版本训练部署指南

简介&#xff1a;本资源是面向计算机视觉初学者与工业检测算法工程师的YOLO系列目标检测专用数据集&#xff0c;聚焦刀具识别这一典型工业质检场景&#xff0c;可直接用于模型训练、验证与测试。压缩包共2000个文件&#xff0c;含1281个VOC格式XML标注文件与719个YOLO格式TXT标…

作者头像 李华
网站建设 2026/10/11 21:46:00

Ceph CRUSH算法详解:Bucket选择、权重调整与重平衡实战

很多搞 Ceph 的朋友第一次接触 CRUSH 算法时&#xff0c;心里都会有个疑问&#xff1a;所有 OSD 明明都参与分布&#xff0c;为什么有的节点磁盘快满了、有的还很空&#xff1f;为什么加了一台机器&#xff0c;整个集群会搬一大堆数据&#xff1f;这些现象背后的账&#xff0c;…

作者头像 李华
网站建设 2026/10/11 21:44:47

MATLAB GPS定位算法仿真框架:从原理到工程验证

简介&#xff1a;本资源是一套面向高校导航工程、测绘科学与自动驾驶方向学习者的MATLAB GPS定位算法仿真程序&#xff0c;聚焦导航定位解算原理的实践验证与教学演示。资源完整实现从GPS信号模拟、伪距/载波相位测量到最小二乘定位解算的全流程&#xff0c;涵盖大气延迟建模、…

作者头像 李华
网站建设 2026/10/11 21:43:55

微信个人名片H5生成器:纯前端轻量级私域触点引擎

简介&#xff1a;这是一款轻量级微信个人名片H5生成器源码&#xff0c;面向前端初学者、个人开发者及小微业务运营者&#xff0c;解决个性化电子名片快速落地需求——无需后端、不依赖第三方接口&#xff0c;纯前端实现头像、姓名、联系方式、个人简介等信息的动态渲染与本地化…

作者头像 李华