整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:

实现分页的最简单的方式(附带源码下载)

实现分页的最简单的方式(附带源码下载)

页是每个网站并不可少的,但是处理往往非常麻烦,虽然有很多的插件可以使用,但复杂度依然不减,今天我们来手敲一个最简单的实现方式,看够之后分页再也不是难题,而且以后用插件也懂原理了。手动擒来!

文章概略:

  1. 分页的原理

  2. 分层实现

  3. 附赠Git开源代码

我们先来说下原理吧,分页就是数据库的数据太多了,一次性查看不完,分批次查看。一般分页分为从数据库处理分页和在服务器端处理分页两大类。

在数据库分页就是用多少数据jdbc去多少数据,比如取100条数据,则用sql语句查询出100条语句就可以了。在服务器分页就是把数据库所有数据都取到服务器,然后客户要多少数据返回多少数据。一般这种方式io要求很高,而且浪费资源。不建议使用,目前开发都是使用第一种方式,编译好sql语句,在数据库服务器处理分页,而且数据库的服务器一般处理速度很快,利用商用。

分页无非就是服务器返回“总页数”和“当前页数”,然后客户端(一般是浏览器)对应处理。我们分层来写。

服务器可以采用java,或者php,或者asp等编写,返回“总页数”和“当前页数”。浏览器采取想应处理。我们采用javascript和html处理,逻辑判断交给js,页面修饰交给css,使用的时候你可以随时改变,方便快捷。

看下预览图(假设每个页面显示10个页数):css代码:用作美化,你可以改成你喜欢的样式

/*分页*/

/*在div paging中的a标签的属性,很简单的css*/

#paging{

width: 80%;

margin: 20px auto 40px auto;

text-align: center;

color: #666666;

font-size: 1.2em;

font-weight: 700;

}

#paging a{

color: #666666;

font-size: 1.2em;

font-weight: 700;

padding:5px 10px;

}

#paging a:hover{

background-color: #FF464E;

color: #F5F5F5;

}

html代码:

javascritp进行的逻辑判断,就是用来个document.writer,简单吧

备注:我是有的是java编写的,用了ssm框架,而且url是RESTful风格的,你可以改成普通风格的,代码注释很详细,我在这不解释了。

RESTful风格:http://localhost:8080/youxuan/index/2

普通风格:http://localhost:8080/youxuan/index?page=2

最终的结果:

总页数小于10页时(共6页),全部显示,访问第1页如下:

总页数大于10,当前页数小于10时,显示前10页,访问第2页如下:

总页数大于10,当前页数大于10时,我们让他显示左右各5页,但是考虑增加5页可能超出总页数。我们增加判断以后结果如下:

当前页+5页没超出总页数,显示当前页左右各5页,访问第10页如下:

当前页+5页超出总页数,显示到最后一页并向前显示10页,访问第20页(最后一页)如下:
实现代码如下:

<script>

/*

分页:接收参数:总页数,当前页数

默认一个页面显示10个页数

可能的情况:

总页数小于10页

全部显示

总页数大于10页

当前页小于10页,显示前10页

当前页大于10页,显示左右各5页

当前页数+5页大于总页数,显示到最后一页

否则显示左右各5页

*/

var path="${ pageContext.request.contextPath }";//获得当前应用的地址现在是 /youxuan

var url=path+"/index";//a标签的地址

//el表达式取得当前页和总页数

var nowPage=${Paging.nowPage};//当前页

var countPage=${Paging.countPage};//总页数

var count=10;//页面显示多少记录,默认每页显示10个记录

//判断“首页”是否显示

if(nowPage>1){

document.writeln(" <a href=\""+url+"/1\">首页</a>");//采用RESTful格式url

}

//总页数小于10页,显示全部页

if(countPage<=count){

for (var i=1;i<=countPage;i++) {

document.writeln(" <a href=\""+url+"/"+i+"\">"+i+"</a>");//采用RESTful格式url

}

}else{

//总页数大于10页

//当前页小于10页,显示前10页

if(nowPage<count){

for (var i=1;i<=count;i++) {

document.writeln(" <a href=\""+url+"/"+i+"\">"+i+"</a>");//采用RESTful格式url

}

//显示省略号和最后一页

document.writeln("...<a href=\""+url+"/"+countPage+"\">"+countPage+"</a>");

}else{

//当前页数大于等于10页,左右各显示5页

if (nowPage <=countPage) {

//当前页+5大于总页数,显示到最后一页,显示前10页

if (nowPage + 5 >=countPage) {

for (var i=nowPage - 10; i <=countPage; i++) {

document.writeln(" <a href=\"" + url + "/" + i + "\">" + i + "</a>");//采用RESTful格式url

}

} else {

//当前页+5小于总页数,左右各显示5页

for (var i=nowPage - 5; i <=nowPage + 5; i++) {

document.writeln(" <a href=\"" + url + "/" + i + "\">" + i + "</a>");//采用RESTful格式url

}

//显示省略号和最后一页

document.writeln("...<a href=\"" + url + "/" + countPage + "\">" + countPage + "</a>");

}

}

}

}

//判断尾页是否显示

if(nowPage<countPage){

document.writeln(" <a href=\""+url+"/"+countPage+"\">尾页</a>");

}

</script>

最好我们最好加个“跳转到第几页的功能”,如图实现代码:

到<input type="number" id="page" style="width: 80px;"/>页

<input type="button" onclick="goPage()" value="转到" style="background-color: #6c6c6c;padding: 6px; color: #F5F5F5;border: 0"/>

</div>

<script>

//跳转到第几页

function goPage() {

var page=document.getElementById("page").value;

var type=/^[1-9]+$/;

var re=new RegExp(type);

if (page.match(re)==null) {

//输入格式错误

alert("亲,页数一个正整数哦~");

}else {

//判断是否大于总页数

if(page>countPage){

alert("亲,总共只有"+countPage+"页呢~");

}else {

window.location.href=url+"/"+page;

}

}

}

</script>

这个这么简单,就不解释了吧。

最后,我们说一下后台实现,我用的是ssm框架,封装了一个分页的bean,代码如下

package com.youxuan.util;

/**

* Created by 两毛五哥哥 on 2016/8/26.

* 分页工具类

*/

public class Paging {

private int countDate;//总数据

private int countPage;//总页数

private int nowPage;//当前页数

private int pageCount;//每页显示多少数据

/**

* 构造函数

* @param countDate

* @param pageCount

* @param nowPage

*/

public Paging(int countDate,int pageCount,int nowPage){

this.countDate=countDate;

this.pageCount=pageCount;

this.nowPage=nowPage;

if(countDate%pageCount==0){

this.countPage=countDate/pageCount;

}else {

this.countPage=countDate/pageCount+1;

}

}

/**

* 构造函数,默认每页显示100条数据

* @param countDate

* @param nowPage

*/

public Paging(int countDate,int nowPage){

this(countDate,100,nowPage);

}

public int getCountDate() {

return countDate;

}

public void setCountDate(int countDate) {

this.countDate=countDate;

}

public int getCountPage() {

return countPage;

}

public void setCountPage(int countPage) {

this.countPage=countPage;

}

public int getNowPage() {

return nowPage;

}

public void setNowPage(int nowPage) {

this.nowPage=nowPage;

}

public int getPageCount() {

return pageCount;

}

public void setPageCount(int pageCount) {

this.pageCount=pageCount;

}

}

然后再servlet(controller)中返回这个封装的对象。你可以不用封装也行,我觉的这样可移植性好,下次做项目直接拿来用了。这个项目我做完会开源贡献的,喜欢的点个赞吧。

最后:git代码下载地址:https://git.oschina.net/lovepeng/share-for-you.git

@两毛五哥哥,90逗逼程序员,欢迎骚扰

列表显示数据时,分页显示是必不可少的功能,活不多说,直接干货拿走,django提供了一个分页器Paginator,下面的例子说明如何使用它。


1,写一个带分页功能的查询方法

编辑 myweb\web\views.py文件,加入如下代码


from models import Tasks

from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger

from django.views.decorators import csrf


#任务列表

def task_list(request):

contact_list=Tasks.objects.all().order_by('-task_start_date')

#每页显示25条

paginator=Paginator(contact_list, 25)

page=request.GET.get('page')

try:

contacts=paginator.page(page)

except PageNotAnInteger:

contacts=paginator.page(1)

except EmptyPage:

contacts=paginator.page(paginator.num_pages)


return render(request, 'taskList.html', {'contacts': contacts})


这里是将数据返回到前端页面 taskList.html页面。



2,前端页面获取并显示数据

在myweb\web\templates目录新建一个taskList.html文件,内容如下:

{% extends 'base.html' %}

{% block content %}

<table class="tableList">

<thead>

<tr>

<th>任务名称</th>

<th>操作者</th>

<th>任务描述</th>

<th>开始日期</th>

<th>结束日期</th>

<th>任务评价</th>

</tr>

</thead>

<tbody>

{% if contacts.paginator.count > 0 %}

{% for contact in contacts %}

<tr>

<td> {{ contact.task_name }} </td>

<td> {{ contact.task_user }} </td>

<td> {{ contact.task_describe }}</td>

<td> {{ contact.task_start_date }} </td>

<td> {{ contact.task_end_date }} </td>

<td> {{ contact.task_result }}</td>

</tr>

{% endfor %}

{% else %}

<tr>

<td colspan="10" align="center">没有任务数据</td>

</tr>

{% endif %}

</tbody>

</table>



{# 分页HTML代码 #}

<div class="pagination">

<span class="step-links">

{% if contacts.has_previous %}

<a href="?page={{ contacts.previous_page_number }}">上一页</a>

{% endif %}


<span class="current">

Page {{ contacts.number }} of {{ contacts.paginator.num_pages }}.

</span>


{% if contacts.has_next %}

<a href="?page={{ contacts.next_page_number }}">下一页</a>

{% endif %}

</span>

</div>

{% endblock %}


3,URL映射

编辑urls.py文件,加入:


url(r'^tasklist/', views.task_list),

要涉及到数据查询,通常我们都会进行分页查询。

假设你的表中有上百万条记录,不分页的话,我们不可能一次性将所有数据全部都载入到前端吧,那前后端都早就崩溃了。

结合 Spring

Spring 和 Vue 都提供了开箱即用的分页功能。

Spring 主要用来处理后端的分页查询,VUE 主要在前端展示页面和进行下一个页面的查询。

有关后端 Spring 如何进行分页查询的方法,请参考:Spring Data @Repository 的分页查询 中的文章。

如果你配置得当,Spring 会将整个查询的页面信息发送给前端。

比如我们说的这一部分,在这部分中,我们会知道总共查询的记录有多少,每一页的大小,一共有多少页,当前是第几页等分页最重要的信息。

VUE

VUE 的前端可以用 Pagination 这个组件 Pagination | Components | BootstrapVue

我们直接在前端调用模板,将参数设置进来就完成了。

代码可以精简到只有下面几句话:

            <b-pagination
                v-model="pagedData.number"
                :total-rows="pagedData.totalElements"
                :per-page="pagedData.size"
                @click="pageSearch(pagedData.number -1)"
                class="pagination pagination-rounded justify-content-end mb-2"
            ></b-pagination>

不用重复做无用的事情了。

第一个参数是当前的页面是第几页。

第二个参数为一共有多少条记录。

第三个参数为当前分页的页面大小。

第四个参数为,如果页码被单击了,我们会触发一个什么样的函数,通常这个函数就是通过 AJAX 的调用到后台再获取一次数据。

是不是简单到令人发指。

如果没有这个模板的话,我们需要手写分页,还要算页面编码,真心没必要。

如果想使用不同的 CSS 的话,在分页模板中加入自己的 CSS 就可以了。

我们的分页效果为

页面看起来还非常干净喔。