手摸手,封装一个vue分页组件

关注前端小讴,阅读更多原创技术文章

【组件化】是每一个前端工程师的必备技能,诚然我们将element、iview、vant等UI组件库运用得娴熟自如,实际开发中还是经常需要封装更适合的业务组件,既帮助快速开发、又让代码简洁明了、还能锻炼我们的组件化能力。

梳理思路

node.js官网的分页组件为例,假设我们要实现下面这样的分页:
最终截图4.png

从产品角度梳理思路后,要实现的分页组件有以下特点:
1.当前页页码颜色变化
2.最多显示5个页码,不足5个显示实际数量
3.总页数超过5个时:总页码-当前页>2,则末尾显示省略号;当前页>2,则开头显示省略号
4.总页数超过5个时:当前页为最后1页,则一共显示3个页码;当前页为倒数第二页,则一共显示4个页码;其余均显示5个页码
5.总页数超过5个、且同时满足总页码-当前页>2当前页>2时,当前页总是显示在5个页码的最中间
6.点击最左、最右侧箭头,分别跳转到第1、最后1页

基本结构

先写一个静态的结构:





在父组件引用该组件:



此时效果:将看到一个标准的、大于5页的静态分页:
最终截图.png

props接收值

组件的某些值应该是父组件传递过来的,通过计算后挂载

props: {
  // 内容总数
  total: {
    type: Number,
    default: 0
  },
  // 每页数量
  limit: {
    type: Number,
    default: 10
  },
  // 当前页码
  page: {
    type: Number,
    default: 1
  },
},
data () {
  return {
    pageList: [] // 页码列表
  };
},
computed: {
  // 最大页数
  pageMax () {
    return Math.ceil(this.total / this.limit);
  },
},
onLoad () { // 我的框架是mpvue,vue用created
  this.initData();
},
methods: {
  // 生成pageList页码列表
  initData () {
    this.pageList = []; // 清空页码
    var i = 1;
    do {
      this.pageList.push(i);
      i++;
    } while (i <= this.pageMax);
    this.pageList.length > 5 && (this.pageList = this.pageList.slice(0, 5)); // 最多显示5页
  }
}

父组件传递这些值:

data () {
  return {
    dataList: [], // 列表
    page: 1, // 当前页码
    limit: 20, // 每页数量
  };
},
onLoad () {
  this.getData();
},
methods: {
  getData () {
     // 动态获取列表 - 以后端分页为例
     this.dataList = (await getDataList(this.limit, this.page)).data;
  }
}

此时效果:将根据父组件——也就是使用该组件的页面——的真实数据,渲染分页组件。页码数量大于5不大于5组件内容不同,且当前页码为首页

event事件回调

组件中追加事件,回调给父组件(调用的组件):

methods: {
  // 子组件事件回调:分页
  pageChange (page) {
    this.$emit("page-change", page);
  },
}

父组件执行子组件回调过来的事件:

methods: {
  // 分页
  pageChange (page) {
    this.page = page;
    this.getData();
  },
}

此时效果:点击页码颜色会发生变化,父组件接收到子组件的回调事件,返回一个值page——即当前页码,可根据页码做分页的内容渲染;点击最左、最右侧箭头,分别跳转到第1、最后1页

watch页码变化

由于不同页码要渲染的组件内容不同,因此需要监听页码变化,刷新组件内容;同时total总数更新时,重新加载组件

watch: {
  // 监听页码变化 -> 页码列表更新
  page (val) {
    if (val <= 3) {
      this.pageList = [];
      var i = 1;
      do {
        this.pageList.push(i);
        i++;
      } while (i <= this.pageMax);
      this.pageList.length > 5 && (this.pageList = this.pageList.slice(0, 5)); // 最多显示5页
    } else if (val === this.pageMax) {
      this.pageList = [val - 2, val - 1, val];
    } else if (val === this.pageMax - 1) {
      this.pageList = [val - 2, val - 1, val, val + 1];
    } else {
      this.pageList = [val - 2, val - 1, val, val + 1, val + 2];
    }
  },
  // 监听页码变化 -> 总数更新
  total (val) {
    this.initData();
  }
}

此时效果:组件根据页码变化数量变化,渲染出不同的内容,至此该分页组件全部内容完成

扩展

可以像element和iview那样,为组件追加当前页显示数量下拉框,也可以由父组件决定子组件的样式布局,页码按钮的数量(本例为最大5个)。。。总体思路不变,即:
1.子组件接收值并根据值而改变渲染
2.子组件追加事件,回调给父组件
3.根据需要追加监听

完整代码






api

props:
属性 说明 类型 默认值
total 内容总数 Number 0
limit 每页数量 Number 10
page 当前页码 Number 1
events:
事件名 说明 返回值
page-change 页码改变的回调,返回改变后的页码 当前页码

你可能感兴趣的:(vue.js,组件化,分页)