手写分页器

<template>
  <div class="paginationContainer">
    <button :disabled="current === 1">上一页</button>
    <button
      v-if="startEnd.start > 1"
      @click="current = 1"
      :class="{ active: current === 1 }"
    >
      1
    </button>
    <button v-if="startEnd.start > 2">...</button>

    <button
      @click="current = item"
      v-for="item in ergodicBtn"
      :key="item"
      :class="{ active: current === item }"
    >
      {{ item }}
    </button>

    <button v-if="startEnd.end < totalPage - 1">...</button>
    <button
      v-if="startEnd.end !== totalPage"
      @click="current = totalPage"
      :class="{ active: current === totalPage }"
    >
      {{ totalPage }}
    </button>
    <button :disabled="current === totalPage">下一页</button>
    <button>总共{{ total }}</button>
  </div>
</template>
 
<script>
/**
 * pageSize:9
 * total:100
 * 10
 */
export default {
  name: 'Pagination',
  data() {
    return {
      current: this.currentNum,
    }
  },
  props: {
    // 数据总共多少条
    total: {
      type: Number,
      default: 100,
    },
    // 当前点击
    currentNum: {
      type: Number,
      default: 5, // 2 ==> 1 2 3 4 5  5 ==>1  ...  3 4 5 6 7 ... 10
    },
    // 一页显示多少条
    pageSize: {
      type: Number,
      default: 10,
    },
    // 连续页码数量
    pagerCount: {
      type: Number,
      // 大于等于 5 且小于等于 21 的奇数
      validator: (value) => {
        return value >= 5 && value <= 21 && value % 2 === 1
      },
      default: 5,
    },
  },
  computed: {
    // 总共页码的数量
    totalPage() {
      return Math.ceil(this.total / this.pageSize)
    },
    startEnd() {
      const { totalPage, current, pagerCount } = this
      let start, end, needNum
      // 先判断你的总的数据是否小于连续页码数量
      // totalPage = 3  连续页码数量 5
      // start = 1 end = 3
      if (totalPage < pagerCount) {
        start = 1
        end = totalPage
      } else {
        /**
         * 正常情况 连续页码数量 5
         * 5 ==> 3 4 5 6 7
         * 4 ==> 2 3 4 5 6 
         * start = currentNum - Math.floor(5 / 2)
           end = currentNum + Math.floor(5 / 2)
         */
        start = current - Math.floor(pagerCount / 2)
        end = current + Math.floor(pagerCount / 2)
        // 左侧范围限定
        if (start < 1) {
          /**
           *
           * start < 1
           *
           * 2 ==>  0 1 2 3 4 ==> 1 2 3 4 5
           * 1 ==> -1 0 1 2 3 ==> 1 2 3 4 5
           */
          needNum = 1 - start // 1   2
          start += needNum // 1    1
          end += needNum // 5    5
        }

        // 右侧范围限定
        if (end > totalPage) {
          /**
           * 9 ==> 7 8 9 10 11 ==> 6 7 8 9 10
           * 10 ==> 8 9 10 11 12 ==> 6 7 8 9 10
           */
          needNum = end - totalPage // 11 - 10 ==> 1    12 - 10 ==> 2
          start -= needNum // 6  6
          end -= needNum // 10  10
        }
      }
      return {
        start,
        end,
      }
    },
    // 需要遍历的按钮
    ergodicBtn() {
      // 1 2 3 4 5 6 7 8 9 10 ==> start = 2 end = 6  =>  2 3 4 5 6
      let arr = []
      const { start, end } = this.startEnd
      for (let i = start; i <= end; i++) {
        arr.push(i)
      }
      return arr
    },
  },
}
</script>

<style lang='less' scoped>
.paginationContainer {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  button {
    min-width: 30px;
    height: 28px;
    line-height: 28px;
    text-align: center;
    border: none;
    outline: none;
    border-radius: 2px;
    margin-right: 5px;
    background-color: #ccc;
    cursor: pointer;
    user-select: none;
    & > :last-child {
      margin-right: 0;
    }
    &:hover {
      background-color: skyblue;
      color: #fff;
    }
    &.active {
      background-color: skyblue;
      color: #fff;
    }
    &:disabled {
      cursor: not-allowed;
    }
  }
}
</style>

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值