利用Vue封装一个简易分页器组件

分页器用来做些什么?


首先我们需要明白的是,我们前端工作是向后端发送请求,然后获取相应的数据后在页面上进行展示。那么如果后端传递过来的数据非常的多,如果一次性全部展示这些数据,那么会出现页面带宽消耗大页面加载缓慢除此之外并不是所有的数据用户都需要,那么就造成了资源的浪费,而引入分页器的话就可以限制每一页展示的数据,用户可以根据需要来进行切换。

分页器组件的封装

  • 首先需要明白几个问题:
  1. 当前是第几页?
  2. 总共多少条数据?
  3. 每一页展示多少数据?
  4. 连续的页数是多少?
  5. 总的页数?
  • 其中连续的页数是多少?完成这个内容的计算,那么分页器就完成了一半。
    • 首先要明白什么是连续的页?
      • ​​​​​​​其实就是在分页器中连续存在的页,比如:下图红色矩形框中的就属于连续的页。
      • 在代码中有相应的文字解释,这儿不过多赘述

                

效果展示:

 

代码如下:

<template>
  <div class="page">
      <button
       @click="sendPageNo(currentPageNo - 1)"
       :disabled="currentPageNo==1"
      >上一页</button>
      <button 
            :class="{active:currentPageNo==1}"
            v-if="startAndEndPageNum[0] > 1"
            @click="sendPageNo(1)"
       >1</button>
      <button v-if="startAndEndPageNum[0]>2">...</button>
      <button 
        v-for="(end,index) in startAndEndPageNum[1]" 
        :key="index"
        v-show="end >= startAndEndPageNum[0]"
        :class="{active:currentPageNo==end}"
        @click="sendPageNo(end)"
      >{{end}}</button>
      <button v-if="startAndEndPageNum[1]<totalPages-2">...</button>
      <button 
        :class="{active:currentPageNo==totalPages}"
        v-if="startAndEndPageNum[1] < totalPages" 
        @click="sendPageNo(totalPages)"
      >{{totalPages}}</button>
      <button
        @click="sendPageNo(currentPageNo+1)"
        :disabled="currentPageNo==totalPages"
      >下一页</button>
  </div>
</template>

<script>
export default {
    name: 'Pagination',
    /**
     *  currentPageNo: 当前在第几页
        total: 总的数据量
        pageSize: 每一页多少条数据
        continuousPage: 连续的页数
     */
    props: ['currentPageNo','total','pageSize','continuousPage'],
    computed: {
        // 计算出总的页数
        /**
         * 例如:总的数据量为:81   每一页的展示数据为:3
         * totalPages: 81/3 = 26....3
         * 
         * 向上取整的原因:
         * 计算出的结果为:26页,回推一步那么可以展示的数据为78
         * ,那就是还需要一页才能展示完毕,所以需要向上取整
         */
        totalPages(){
            return Math.ceil( this.total / this.pageSize );
        },
        // 起始的页码和终止的页码
        startAndEndPageNum(){
            const {continuousPage, totalPages, currentPageNo} = this;
            // 用于记录开始页码和终止页码
            // 起始的值和终止的值
            let start = currentPageNo - parseInt(continuousPage / 2);
            let end = currentPageNo + parseInt(continuousPage / 2);
            // 如果连续的页码大于等于总页码
            if(continuousPage >= totalPages){
                start = 1;
                end = totalPages;
            }
            // 判断起始的页码和终止的页码
            // 起始的页码不能小于1,因为页码不能出现0页吧
            if (start < 1){
                start = 1;
                end = continuousPage;//保证连续的页数
            }
            // 终止的页码,不能超出总的页数
            if(end > totalPages){
                /**
                 *   28 29 30(current) 31 32
                 */
                start = start - (end - totalPages);//保证连续的页数
                end = totalPages;
            }
            return [start,end];
        }
    },
    methods: {
        // 用于其他组件引用时,发送当前点击的页吗
        sendPageNo(pageNo){
            // getPageNo(pageNo);
            this.$emit('getPageNo',pageNo)
        }
    },
}
</script>

<style  scoped>
    .page {
        text-align: center;
        margin-top: 100px;
    }
    .page>button {
      margin: 0 3px;
      background-color: #f4f4f5;
      color: #606266;
      outline: none;
      border-radius: 2px;
      padding: 0 4px;
      vertical-align: top;
      display: inline-block;
      font-size: 13px;
      min-width: 35.5px;
      height: 28px;
      line-height: 28px;
      cursor: pointer;
      box-sizing: border-box;
      text-align: center;
      border: 0;
        
    }
    /* 设置拥有disabled属性的按钮的鼠标样式 */
    .page>button[disabled] {
        color: #c0c4cc;
        cursor: not-allowed;
    }
    .page>button.active {
        background-color: #409eff;
        color: #fff;
    }

</style>

App.vue中测试代码:

<template>
<!-- 
  以下数据为测试数据
  currentPageNo: 30 当前第几页
  total: 91         总共的数据条数
  pageSize: 3       每一页多少条数据
  continuousPage: 5  连续的页码数 
 -->
<!-- getPageNo这个自定义事件,作用是发送网络请求改变currentPageNo
 -->
  <!-- <Pagination 
    :currentPageNo="31"
    :total="91"
    :pageSize="3"
    :continuousPage="5"
    @getPageNo="getPageNo"
  /> -->
    <Pagination 
    :currentPageNo="currentPageNo"
    :total="91"
    :pageSize="3"
    :continuousPage="5"
    @getPageNo="getPageNo"
  />
</template>

<script>
import Pagination from './components/pagination'
export default {
  name: 'App',
  data() {
    return {
      currentPageNo: 1
    }
  },
  components: {
    Pagination
  },
  methods: {
    getPageNo(pageNo){
      this.currentPageNo = pageNo;
    }
  },
}
</script>

<style>
  * {
    margin: 0;
    padding: 0;
  }
</style>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值