账户中心 退出系统
开发文档 资讯·分享 技术交流 会员登录
phpGrace GSCMS 公众号系统
查询分页

分页场景及实现方案

# 场景1 : 点击链接 url 跳转方式
实现 :控制内部使用 page() 分页,视图端使用 a 链接形式实现跳转;

# 场景2 : 响应式渲染 + 页码 ( 如 : 使用 vue.js 为基础的后端管理系统 )
实现 :控制内部使用 page() 分页,视图端使用 事件跳转;

# 场景3 : api 结果,上拉加载更多、下拉刷新
实现 : 通过 limit 实现即可 limit( (页码 - 1) * 每页展示数量,每页展示数量 )

本节教程适用于 场景 1 和 2;

数据分页概述

在询数据时,使用数据操作对象的 page() 函数即可快速完成分页;

page() 分页函数

参数 :

* @param int $currentPage 当前页码,可选参数,默认 1
* @param int $totalRows 数据总数,可选参数,默认 200
* @param int $eachPageNumber 每页展示数量,可选参数,默认 10
* @param int $listMaxNumber 列表页码长度,可选参数,默认 10
* @param string $returnType 返回页面数据形式 [ a : 链接形式, 其他字符,如 event 或 number : 数值形式 ],默认 a
* @param string $pageName url 参数中记录当前页码的键名称,可选参数,默认 page : $_GET['page']

返回 :数据操作对象,使用 fetchAll() 函数连贯操作完成查询;

返回数据格式

使用 page() 函数与 fetchAll() 函数结合查询数据格式如下 : 

$data = array(
    数据列表[ 数组形式 ], 分页数据[ 对象形式 ]
);

分页对象数据格式

$分页数据['firstPage'] //第一页
$分页数据['prePage'] //上一页
$分页数据['listPage'] //列表页
$分页数据['nextPage'] //下一页
$分页数据['lastPages'] //最后一页
$分页数据['currentPage'] //当前页码

示例 1 链接形式 ( 函样式 ) 

控制器代码

<?php
namespace grace\controller;
use grace\grace;
use grace\database;
class index extends grace{
    public function index(){
        // 利用 $_GET['page'] 传递页码
        $_GET['page']        = empty($_GET['page']) ? 1 : $_GET['page'];
        // 使用 $this-> 将对象和数据注册为控制器数据 共享给视图
        $this->studentsTable = database::table('students');
        // 利用 $_GET['total'] 保存总数,
        // 第一次查询或者 url 没有保存总数则查询数据总数
        if(empty($_GET['total'])){
            $_GET['total'] = $this->studentsTable->count();
        }
        $this->students      = $this->studentsTable
            ->order('st_id desc')
            ->page($_GET['page'], $_GET['total'], 2, 10, 'a')
            ->fetchAll();
    }
}

视图文件代码

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1" />
</head>
<body>
<div style="padding:100px;">
    <ul>
        <?php foreach($this->students[0] as $student){?>
        <li>id : <?php echo $student['st_id'];?> 姓名 : <?php echo $student['st_name'];?> 年龄 : <?php echo $student['st_age'];?></li>
        <?php }?>
    </ul>
    <div class="pager-list">
        <?php echo $this->students[1]['firstPage'];?>
        <?php echo $this->students[1]['prePage'];?>
        <?php echo $this->students[1]['listPages'];?>
        <?php echo $this->students[1]['nextPage'];?>
        <?php echo $this->students[1]['lastPage'];?>
    </div>
</div>
<style>
    li{list-style:none;}
    .pager-list{margin-top:15px;}
    .pager-list .pager{display:block; font-size:14px; color:#333333; background:#F5F5F5; padding:0px 10px; height:30px; line-height:30px; float:left; margin-right:5px; border-radius:2px; cursor:pointer; text-decoration:none;}
    .pager-list .pager:hover{background:#2F4056; text-decoration:none; color:#FFFFFF !important;}
    .pager-list .pager:visited{color:#333333;}
    .pager-list .current{background:#5FB878 !important; color:#FFF !important;}
</style>
</body>
</html>

示例 2 响应式数据渲染示例 ( vue.js ) 

控制器代码

<?php
namespace grace\controller;
use grace\grace;
use grace\database;
use grace\http\response;

class index extends grace{
    // index 方法用于展示视图
    public function index(){}

    // 数据请求方法
    public function getStudents(){
        // 利用 $_GET['page'] 传递页码
        $_GET['page']        = empty($_GET['page']) ? 1 : $_GET['page'];
        // 使用 $this-> 将对象和数据注册为控制器数据 共享给视图
        $this->studentsTable = database::table('students');
        // 利用 $_GET['total'] 保存总数,
        // 第一次查询或者 url 没有保存总数则查询数据总数
        if(empty($_GET['total'])){
            $_GET['total'] = $this->studentsTable->count();
        }
        $this->students      = $this->studentsTable
            ->order('st_id desc')
            ->page($_GET['page'], $_GET['total'], 2, 6, 'event')
            ->fetchAll();
        response::json(true, $this->students);
        // 此处结束程序继续运行,编码调试信息输出
        exit;
    }
}

视图文件代码

<!DOCTYPE html>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1" />
<script type="text/javascript" src="http://lib.sinaapp.com/js/jquery/3.1.0/jquery-3.1.0.min.js"></script>
<script src="https://unpkg.com/vue@next"></script>
<style>
li{list-style:none;}
.pager-list{margin-top:15px;}
.pager-list .pager{display:block; font-size:14px; color:#333333; background:#F5F5F5; padding:0px 10px; height:30px; line-height:30px; float:left; margin-right:5px; border-radius:2px; cursor:pointer; text-decoration:none;}
.pager-list .pager:hover{background:#2F4056; text-decoration:none; color:#FFFFFF !important;}
.pager-list .pager:visited{color:#333333;}
.pager-list .current{background:#5FB878 !important; color:#FFF !important;}
.loading{position:fixed; width:100%; height:100%; text-align:center; font-size:15px; line-height:300px; color:#FFFFFF; z-index:99; left:0; top:0; bottom:0; background:rgba(0,0,0,0.8);}
</style>
</head>
<body>
<div style="padding:100px;" id="app">
    <div style="font-size:15px; text-align:center;" v-if="students == null"></div>
    <ul v-if="students != null">
        <li v-for="(student, idx) in students">
            id : {{student.st_id}} 姓名 : {{student.st_name}} 年龄 : {{student.st_age}}
        </li>
    </ul>
    <div class="pager-list" v-if="pager != null">
        <div class="pager" @click="page(pager.firstPage)">首页</div>
        <div class="pager" @click="page(pager.prePage)">上一页</div>
        <div class="pager"
             :class="[currentPage == pageItem ? 'current' : '']"
             v-for="(pageItem, idx) in pager.listPages" @click="page(pageItem)">{{pageItem}}</div>
        <div class="pager" @click="page(pager.nextPage)">下一页</div>
        <div class="pager" @click="page(pager.lastPage)">尾页</div>
    </div>
    <!-- loading -->
    <div class="loading" v-if="loading">加载中 ...</div>
</div>
<script>
const App = {
    data() {
        return {
            // 学生数据
            students    : null,
            // pager 分页数据
            pagers      : null,
            // 当前页码
            currentPage : 0,
            // 数据总数
            total       : 0,
            // 加载中
            loading     : true
        }
    },
    created : function () {
        this.getStudents(1);
    },
    methods:{
        getStudents : function (pageNumber) {
            if(pageNumber == this.currentPage){return ;}
            this.loading = true;
            this.currentPage = pageNumber;
            // ajax 请求获取数据
            var url = '/index/getStudents/page/'+this.currentPage+'/total/'+this.total;
            console.log(url);
            $.get(
                url,
                (res)=>{
                    console.log(res);
                    this.students = res.data[0];
                    this.pager    = res.data[1];
                    this.total    = res.data[1].totalRows;
                    setTimeout(()=>{this.loading  = false;}, 1000)
                }
            );
        },
        page : function (pageNumber) {
            this.getStudents(pageNumber)
        }
    }
}
Vue.createApp(App).mount('#app');
</script>
</body>
</html>