node.js+mongoose+vue实现分页

效果图

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


分页.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实现分页)