实现一个简单分页器

在go web编程中,当需要展示的列表数据太多时,不可避免需要分页展示,可以使用Go实现一个简单分页器,提供各个数据列表展示使用。
具体需求:
1. 可展示“首页”和“尾页”。
2. 可展示“上一页”和“下一页”。
3. 展示一定数量的数字页码,但总保持当前访问页码在中间位置。
分页器代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
package paginator
 
import (
    "math"
)
 
//分页器结构
type paginator struct {
    Total     int   //记录总数
    PageSize  int   //每页大小
    PageTotal int   //总页数
    Page      int   //当前页数
    LastPage  int   //上一页
    NextPage  int   //下一页
    PageNums  []int //显示页码
}
 
var defaultPageSize = 5 //默认页大小
var pageNum = 5         //显示页码数量
 
//获取默认页大小
func GetDefaultPageSize() int {
    return defaultPageSize
}
 
//设置默认页大小
func SetDefaultPageSize(ps int) {
    if ps < 1 {
        ps = 1
    }
    defaultPageSize = ps
}
 
//设置显示页码数量
func SetPageNum(pn int) {
    if pn < 1 {
        pn = 1
    }
    pageNum = pn
}
 
//创建分页器
func CreatePaginator(page, pageSize, total int) paginator {
    if pageSize <= 0 {
        pageSize = defaultPageSize
    }
    pager := &paginator{
        Total:     total,
        PageSize:  pageSize,
        PageTotal: int(math.Ceil(float64(total) / float64(pageSize))),
        Page:      page,
    }
    if total <= 0 {
        pager.PageTotal = 1
        pager.Page = 1
        pager.LastPage = 1
        pager.NextPage = 1
        pager.PageNums = append(pager.PageNums, 1)
        return *pager
    }
    //分页边界处理
    if pager.Page > pager.PageTotal {
        pager.Page = pager.PageTotal
    } else if pager.Page < 1 {
        pager.Page = 1
    }
    //上一页与下一页
    pager.LastPage = pager.Page
    pager.NextPage = pager.Page
    if pager.Page > 1 {
        pager.LastPage = pager.Page - 1
    }
    if pager.Page < pager.PageTotal {
        pager.NextPage = pager.Page + 1
    }
    //显示页码
    var start, end int //开始页码与结束页码
    if pager.PageTotal <= pageNum {
        start = 1
        end = pager.PageTotal
    } else {
        before := pageNum / 2         //当前页前面页码数
        after := pageNum - before - 1 //当前页后面页码数
        start = pager.Page - before
        end = pager.Page + after
        if start < 1 { //当前页前面页码数不足
            start = 1
            end = pageNum
        } else if end > pager.PageTotal { //当前页后面页码数不足
            start = pager.PageTotal - pageNum + 1
            end = pager.PageTotal
        }
    }
    for i := start; i <= end; i++ {
        pager.PageNums = append(pager.PageNums, i)
    }
    return *pager
}

控制器使用:

1
2
3
4
5
6
7
8
9
10
11
pager := paginator.CreatePaginator(page, pageSize, total)
tpl, err := template.New("index.html").ParseFiles("index.html")
if err != nil {
    fmt.Fprint(writer, "模板解析错误:", err)
    return
}
err = tpl.Execute(writer, map[string]interface{}{"paginator": pager})
if err != nil {
    fmt.Fprint(writer, "模板执行错误:", err)
    return
}

模板使用:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
#pageBar {
    text-align: right;
    padding: 20px 0 20px 0;
}
.pageBtn a {
    display: inline-block;
    border: 1px solid #aaa;
    padding: 2px 5px;
    margin : 0 3px;
    font-size: 13px;
    background: #ECECEC;
    color: black;
    text-decoration: none;
    -moz-border-radius: 2px;
    -webkit-border-radius: 3px;
}
.pageBtn-selected a {
    display: inline-block;
    border: 1px solid #aaa;
    padding: 2px 5px;
    margin : 0 3px;
    font-size: 13px;
    background: #187BBD;
    color: white;
    text-decoration: none;
    -moz-border-radius: 2px;
    -webkit-border-radius: 3px;
}
.pageBtn a:hover {
    background: #187BBD;
    color: white;
}
<div class="row" id="pageBar">
     {{if ne .paginator.Page 1}}
         <span class="pageBtn"><a href="/address/1/{{.paginator.PageSize}}">首页</a></span>
         <span class="pageBtn"><a href="/address/{{.paginator.LastPage}}/{{.paginator.PageSize}}">上一页</a></span>
     {{end}}
     {{range $k, $v := .paginator.PageNums}}
         {{if eq $v $.paginator.Page}}
              <span class="pageBtn-selected"><a href="/address/{{$v}}/{{$.paginator.PageSize}}">{{$v}}</a></span>
         {{else}}
              <span class="pageBtn"><a href="/address/{{$v}}/{{$.paginator.PageSize}}">{{$v}}</a></span>
         {{end}}
     {{end}}
     {{if ne .paginator.Page .paginator.PageTotal}}
          <span class="pageBtn"><a href="/address/{{.paginator.NextPage}}/{{.paginator.PageSize}}">下一页</a></span>
          <span class="pageBtn"><a href="/address/{{.paginator.PageTotal}}/{{.paginator.PageSize}}">尾页</a></span>
     {{end}}
</div>

效果:

posted @   疯一样的狼人  阅读(675)  评论(0编辑  收藏  举报
编辑推荐:
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
点击右上角即可分享
微信分享提示