美文网首页
node.js+mongoose+vue实现分页

node.js+mongoose+vue实现分页

作者: cwjbest | 来源:发表于2017-11-20 14:46 被阅读117次

    效果图

    先来个效果图,如果觉得丑,就不用往下看了。。。。


    分页.png

    实验环境:

    名称 版本号
    mongodb 3.5.3
    node.js 9.1.0
    Vue.js 2.5.6

    详细代码

    环境搭建我就不说了,直接说说思路吧。功能基本上就这些:

    1. 任意点击某一页
    2. 上一页,下一页
    3. 前五页, 后五页
    4. 搜索任意页
    5. 显示总页数
    初始化

    首先需要初始化从后台拿到表中总的记录数count,然后根据我们预先设定的page_size(每页显示多少条数据),来计算出总的页数(page_count)。本文中,page_size=10, 页码表默认是显示5个。

    data() {
          return {
            all_user_data: "",
            count: "",//总记录数
            page_count: "",//总页数
            page_size: 10,//每页显示记录条数
            page_now: 1,//当前页
            page_num: null,//搜索页
            list: []//页码表
          }
        },
    
     initpage() {
            this.api_name = this.$route.query.api_name;
            this.$http.get(this.GLOBAL.apiurl + "/api/" + this.api_name).then((response) => {
              console.log(response.body.data);
              this.all_user_data = response.body.data;
            });
    
            this.$http.get(this.GLOBAL.apiurl + "/api/" + this.api_name + "_count").then((response) => {
              console.log(response.body.data);
              this.count = response.body.data;
              this.page_count = Math.ceil(this.count / this.page_size);
              for (var i = 1; i <= this.page_count; i++) {
                this.list[i - 1] = i;
                if (i >= 5) {
                  break;
                }
              }
            });
          },
    

    这里计算总页数的时候要注意,如果最后一页不够10条数据,也要计算在内

    this.page_count = Math.ceil(this.count / this.page_size);
    

    所以我们用(count/page_size)然后整个向上取整计算出总的页数。注意啊,js中''/''计算的结果不是整数,而是小数。。。
    这里总共向后台发了两个请求,一个是拿回第一页的10条数据,一个是拿到总的记录数,初始化页码表。来看看后台这两个函数

    apiRoutes.get('/你自己的url', function (req, res) {
        console.log("--------------------------------------------------");
        let page_now = req.query.page_now;
        console.log(page_now);
        Student.MFindAllStudents(page_now, function (err, students) {
            if (err) {
                res.json({
                    errno: 1,
                    tips: "查询所有学生操作异常"
                })
            }
            else {
                res.json({
                    errno: 0,
                    data: students
                })
            }
        })
    });
    
    apiRoutes.get('/你自己请求的url', function (req, res) {
        console.log("--------------------------------------------------");
        Student.MCountAllStudents(function (err, count) {
            if (err) {
                res.json({
                    errno: 1,
                    tips: "查询总数操作异常"
                })
            }
            else {
                res.json({
                    errno: 0,
                    data: count
                })
            }
        })
    });
    
    exports.MFindAllStudents = function(page_now, callback){
        Student.find(function(err,student){
            callback(err,student);
        }).limit(10).skip(page_now*10);
    };
    
    exports.MCountAllStudents = function(callback){
        Student.count(function(err,count){
            callback(err,count);
        });
    };
    

    Student是表的映射,后台使用了mongoose模块来做数据库操作,在find语句后面加上
    limit(10).skip(1)就代表从第一页开始显示,每页显示10条数据。这个就是分页的核心了,所有的操作都是在调这个函数。

    好了,现在对应着每一个功能来看

    1. 任意点击某一页
    click_page: function (page_now) {
            let data = {page_now: page_now - 1};
            this.api_name = this.$route.query.api_name;
            this.$http.get(this.GLOBAL.apiurl + "/api/" + this.api_name, {params: data}).then((response) => {
              console.log(response.body.data);
              this.all_user_data = response.body.data;
            });
            this.page_now = page_now;
     },
    

    将 当前页码-1 传到后台,为啥减1不谈了,看看上面的skip机制就知道了。

    1. 上一页,下一页
    click_next_one: function () {
            if (this.page_now * this.page_size < this.count) {
              if (this.page_now === this.list[this.list.length - 1]) {
                for (var i = 0; i < this.list.length; i++) {
                  this.list[i] += 1;
                }
              }
              this.page_now += 1;
              this.click_page(this.page_now)
            } else {
              alert("已到最后一页");
            }
      },
    
     click_pre_one: function () {
            if (this.page_now > 1) {
              if (this.page_now === this.list[0]) {
                for (var i = 0; i < this.list.length; i++) {
                  this.list[i] -= 1;
                }
              }
              this.page_now -= 1;
              this.click_page(this.page_now)
            } else {
              alert("已到第一页");
            }
      },
    

    先看下一页,如果是末页的话没有下一页,所以先来一个过滤。然后这个循环体主要是实现了这么一个效果,就是当前页是页码表的最后一页时(比如第5页),下一页之后会使页码表每个都后延一个数,看图:


    下一页1.png
    下一页2.png

    上一页的情况是一样的,注意的是,不用再向后台请求数据,只需要调用已经写好的click_page函数即可。

    1. 前五页, 后五页
         click_pre_more: function () {
            if (this.list[0] > 5) {
              for (var i = 0; i < this.list.length; i++) {
                this.list[i] -= this.list.length;
              }
    
              this.page_now -= this.list.length;
              this.click_page(this.page_now);
            } else {
              this.click_pre_one();
            }
          },
    
          click_next_more: function () {
            //如果每行第一个数加9超了,意味着最后一页会出现不够的情况,那就执行下一页
            if (this.list[0] + this.page_size-1 <= this.page_count) {
              for (var i = 0; i < this.list.length; i++) {
                this.list[i] += this.list.length;
              }
              this.page_now += this.list.length;
              this.click_page(this.page_now);
            } else {
              this.click_next_one();
            }
          }
    

    正常情况时,点击后5页会使页码表更新,每个延后5个位置,并且当前页也会延后5个位置,效果:


    后5页1.png
    后5页2.png

    特殊情况,最后不够5页了怎么办,最好的应该是,最后还剩几页就显示几页,可以我没找到合适的解决方案,就用了另一种方案代替:不够5页时就去调下一页。效果:


    后5页3.png
    后5页4.png

    那前五页的效果跟这个是一样的,只不过判断条件变了以下而已,就不多说了。

    1. 搜索任意页
    click_page_search: function (page_num) {
            if (page_num <= this.page_count && page_num > 0) {
              this.click_page(page_num);
              //正常情况时,搜索页码显示在页码表的首位
              if (page_num + this.list.length - 1 <= this.page_count) {
                for (var i = 0; i < this.list.length; i++) {
                  this.list[i] = page_num + i;
                }
              }else {
                for (var i = 0; i < this.list.length; i++) {
                  this.list[this.list.length-1-i] = page_num - i ;
                }
              }//特殊情况时,搜索页码显示在页码表的末位
            } else {
              alert("兄台,并没有这一页...");
            }
            this.page_num = "";
      },
    

    这个搜索倒是很简单,直接调click_page就行了,关键是你的页码表得跟着更新啊。。。
    /正常情况时,搜索页码显示在页码表的首位(避免了第一页的位置不在页码表的首位)
    效果:


    搜索页1.png

    特殊情况,即搜索页是最后4页时,搜索页码显示在页码表的末位(避免了最后不够5页的情况)。效果:


    搜索页2.png

    总结:

    基本上就是这样了,算法太差了,写的很乱,总是用一些很笨的方法来补救。。。希望以后能有更好的解决方案
    样式是引用了这位前辈的帖子,非常感谢
    Html5实现自己的分页加载

    相关文章

      网友评论

          本文标题:node.js+mongoose+vue实现分页

          本文链接:https://www.haomeiwen.com/subject/kckvvxtx.html