
本文介绍如何在 Go 中实现类似 的智能分页逻辑,支持当前页居中、首尾固定显示、动态省略号插入,无需第三方库,代码轻量、高效且可扩展。
本文介绍如何在 go 中实现类似 `` 的智能分页逻辑,支持当前页居中、首尾固定显示、动态省略号插入,无需第三方库,代码轻量、高效且可扩展。
在 Web 开发中,分页不仅是功能需求,更是用户体验的关键一环。简单列出全部页码(如 1 2 3 ... 200)在数据量大时既低效又难读;而硬编码固定偏移(如“始终显示前后 3 页”)又会在边界页(第 1 页、最后几页)导致逻辑断裂或重复渲染。理想的分页应具备以下特性:
- ✅ 当前页始终可见并居中突出
- ✅ 首部固定显示前
N页(如1 2) - ✅ 尾部固定显示后
M页(如200 201) - ✅ 中间长间隔自动替换为
...(仅当真实省略发生时) - ✅ 时间/空间复杂度为 O(1) —— 仅遍历需渲染的页码,不预分配大数组
下面是一个生产就绪的 Go 分页生成器,采用回调驱动(callback-based)设计,解耦页码计算与 HTML 渲染:
// pages renders pagination items via callback: negative i means ellipsis
func pages(current, around, total, prefix, suffix int, render func(i int)) {
var i int
// Render prefix: e.g., "1 2"
for i = 1; i <p>使用示例(生成 HTML 片段):</p><pre class="brush:php;toolbar:false;">var html []string
pages(25, 3, 201, 2, 2, func(i int) {
switch {
case i == -1:
html = append(html, `
输出效果(节选):
? 关键设计说明:
-
around控制以当前页为中心的左右扩展数(默认 ±3 → 共 7 个连续页); -
prefix/suffix独立控制首尾固定显示页数(推荐2,兼顾简洁与导航性); -
render(-1)是约定信号,由调用方决定如何渲染省略号(支持 CSS 类、SVG 或无障碍标记); - 无内存泄漏风险:不预分配切片,不缓存中间结果,适合高并发模板渲染场景;
- 可无缝集成 Gin / Echo / Fiber 等框架:将
render替换为c.HTML()或模板变量注入。
⚠️ 注意事项:
-
current必须已校验为1 ≤ current ≤ total,建议前置做参数归一化(如current = clamp(current, 1, totalPages)); - 若需支持「上一页/下一页」按钮,应在
pages()外围手动拼接; - 对 SEO 友好:确保所有
<a></a>标签含有效href,禁用 JavaScript 时仍可跳转; - 如需国际化(如多语言省略号),将
"..."提取为配置项或本地化函数。
该方案摒弃了 Laravel 风格的“全量生成再裁剪”,转而采用流式构造(streaming construction)——每一步只决策“下一个该输出什么”,逻辑清晰、边界鲁棒、性能恒定,是 Go 生态中符合惯用法(idiomatic Go)的分页实践范本。










