第41讲 前端分页参数的处理
本讲基于视频实际讲解内容整理
一、本讲概述
数据一多就要分页:每页显示固定条数,通过页码翻页。本讲讲解分页的参数怎么传(page、pageSize)、后端如何用 Limit / Offset 截取数据、如何算总页数,并把分页信息交给模板渲染出翻页按钮。
二、分页参数
2.1 前端传参
HTML
<a href="/?page=1">上一页</a>
<a href="/?page=2">下一页</a>
常用两个参数:
page:当前第几页(从 1 开始)pageSize:每页多少条(也可后端固定)
2.2 后端接收并换算
Go
func Index(c *gin.Context) {
page, _ := strconv.Atoi(c.DefaultQuery("page", "1"))
pageSize := 6
if page < 1 {
page = 1
}
offset := (page - 1) * pageSize
// ...
}
老师强调:
c.DefaultQuery("page", "1")取不到时默认第 1 页。offset是"跳过前面几页",公式为(page-1)*pageSize。
三、用 Limit / Offset 截取数据
Go
var videos []Video
var total int64
DB.Model(&Video{}).Count(&total) // 总条数
DB.Preload("Category").Preload("User").
Order("created_at desc").
Limit(pageSize).Offset(offset).
Find(&videos)
| 方法 | 作用 |
|---|---|
Count(&total) |
统计总记录数 |
Limit(n) |
最多取 n 条 |
Offset(n) |
跳过前 n 条 |
Order(...) |
排序,如最新在前 |
四、计算总页数并传给模板
Go
totalPages := int(total) / pageSize
if int(total)%pageSize != 0 {
totalPages++ // 有余数就多一页
}
c.HTML(200, "index.html", gin.H{
"videos": videos,
"page": page,
"totalPages": totalPages,
"categories": categories,
})
五、模板渲染翻页
HTML
<div class="pager">
{{if gt .page 1}}
<a href="/?page={{sub .page 1}}">上一页</a>
{{end}}
<span>第 {{.page}} / {{.totalPages}} 页</span>
{{if lt .page .totalPages}}
<a href="/?page={{add .page 1}}">下一页</a>
{{end}}
</div>
注意:
{{sub .page 1}}这类运算需要自定义模板函数(见第29讲 FuncMap),或直接由后端算好prevPage/nextPage传进来,更简单:
Go
c.HTML(200, "index.html", gin.H{
"prevPage": page - 1,
"nextPage": page + 1,
// ...
})
HTML
<a href="/?page={{.prevPage}}">上一页</a>
<a href="/?page={{.nextPage}}">下一页</a>
六、本讲小结
| 知识点 | 要点 |
|---|---|
| 参数 | page(当前页)、pageSize(每页条数) |
| 取值 | c.DefaultQuery("page", "1") |
| 偏移 | offset = (page-1) * pageSize |
| 截取 | Limit(pageSize).Offset(offset) |
| 总数 | Count(&total),总页数 = 总数/页大小(向上取整) |
| 翻页 | 后端算 prevPage/nextPage 传给模板最稳 |
七、课后练习
- 在首页 handler 用
c.DefaultQuery取page,算offset - 用
Count统计总数,用Limit/Offset截取当前页数据 - 计算
totalPages(注意向上取整),传给模板 - 由后端算好
prevPage、nextPage传给模板,渲染上一页/下一页 - 给翻页按钮加"当前页高亮""到边界禁用"的判断
- 综合第40讲:实现
?category=1&page=2同时支持分类筛选与分页