lu-Pagination分页器

284 阅读3分钟

目标效果:

image.png

参考:

image.png

问题:

如果后台返回的数据是10 页码要展示多少

那个pageSize默认是取第一个[2,4,6,8]/ [8,10,15,20]

拿到第一个 2 总数/2 = 5 页 10/8 = 1 + 1 = 2 页

解读:

别人的手写

1.有哪些属性:

image.png

image.png

image.png

错误理解:

maxShowPageCard 总数据量大于8时,每个分页组显示数量 图片是有错的

maxShowPageCard 总数据量大于`8`时,每个分页组显示数量  图片是有错的

image.png

image.png

image.png

total 很多就会出现 是有bug的

image.png

image.png

showMaxPage什么时候走 return this.maxShowPageCard

image.png 应该是 初始化的时候返回 0*2 < this.totalPage 0 < 125 和 morePageMid 是62 之前都是走这里

确切一点 morePageMid 为56的之前

image.png

1.测试流程:点击下一组扩展

image.png

image.png 2.中间展示多少条数据

image.png

image.png

点击返回上一个组 回到上一个组的第一位

image.png

image.png

下一页同理

image.png

image.png 问题来了:事件会触发两次

image.png

image.png

切换每页显示的条目个数了

image.png

image.png

参考element ui 其实是没有发送这个事件的

image.png

page.gif

查看element ui 源码:

分析那个前往 输入框跳转指定页码

有几种可能

1.前往当前组看得见的页面 2.前往后面看不到的页面 3.前往超出范围的页面 4.返回原来的页面

image.png

出现bug

image.png

image.png

image.png

在父组件传参:默认一个值 有两种可能

一种是布尔类型 在子组件props 里面是有定义的

image.png

image.png

完整代码:

<template>
  <div class="pragination">
    <i v-if="$attrs.showInfo == ''">共:{{totalPage}}页 / {{total}}条</i>
    <select @change="changePageSize" v-if="$attrs.choosePageSizeBySelect == ''">
      <option v-for="item in pageSizeList" :key="item" :value="item">{{item}}条/页</option>
    </select>
    <i class="el-icon-arrow-left" @click="prevPage" :style="prevDefaultStyle"></i>
    <!-- 前面折叠组 -->
    <span v-if="totalPage > maxShowPageBox && (nowPageNum > morePageMid) && morePageMid !== 0 && total > 50" @click="showPrevPageGroup">...</span>
    <span :class="item == nowPageNum || item + morePageMid == nowPageNum ? 'active' : ''" v-for="item in showMaxPage" :key="item" @click="changePageNum(item)">{{item + morePageMid}}</span>
    <!-- 后面折叠组 -->
    <!-- <span v-if="totalPage > maxShowPageBox && morePageMid * 2 < totalPage && total > 50" @click="showNextPageGroup">...</span> -->
    <span v-if="totalPage > maxShowPageBox && showEndGroup  && total > 50" @click="showNextPageGroup">...</span>
    <i class="el-icon-arrow-right" @click="nextPage" :style="nextDefaultStyle"></i>
    <i v-if="$attrs.showInfo == ''">当前为第 {{nowPageNum}} 页</i>
    <i v-if="$attrs.choosePageNumByInput == ''">
      前往
      <input type="text" class="inputChangePageSize" @blur="inputChangePageSize" @keydown.enter="inputChangePageSize" />页
    </i>
  </div>
</template>

<script>
export default {
  name: 'Pagination',
  props: {
    total: { //数据总数
      type: Number,
      default: 1
    },
    pageSizeList: { //数据总数
      type: Array,
    },
    maxShowPageCard: { //最多展示的页盒子
      type: Number,
      default: 5
    },
    pageNumList: { //select页码选择列表
      type: Array,
    },
    test: {
      type: Boolean,
      default: true
    }
  },
  mounted () { },
  data () {
    return {
      nowPageNum: 1, //当前页码
      usePageSize: this.pageSizeList[0], //每页数量
      maxShowPageBox: this.maxShowPageCard, //最多展示页盒子
      morePageMid: 0, //更多展示页扩展比例
    }
  },
  methods: {
    prevPage () { //上一页
      if (this.nowPageNum > 1) {
        if (this.nowPageNum - 1 < (this.morePageMid + 1)) {
          this.showPrevPageGroup('noRepeatTrigger')
          this.nowPageNum = this.maxShowPageBox + this.morePageMid
        } else {
          this.nowPageNum--
        }
        this.$emit('changePageNum', this.nowPageNum)
      }
    },
    nextPage () { //下一页
      if (this.nowPageNum < this.totalPage) {
        if (this.nowPageNum + 1 > this.maxShowPageBox + this.morePageMid) {
          this.showNextPageGroup('noRepeatTrigger')
        } else {
          this.nowPageNum++
        }
        this.$emit('changePageNum', this.nowPageNum)
      }
    },
    changePageNum (pageNum) { //点击改变页码
      this.nowPageNum = pageNum + this.morePageMid
      this.$emit('changePageNum', this.nowPageNum)
    },
    showPrevPageGroup (noRepeatTrigger) { //展示上一组扩展
      if (this.morePageMid !== 0) {
        this.morePageMid -= this.maxShowPageBox
        this.nowPageNum = this.morePageMid + 1
        if (!noRepeatTrigger) this.$emit('changePageNum', this.nowPageNum)
      }
    },
    showNextPageGroup (noRepeatTrigger) { //展示下一组扩展
      this.morePageMid += this.maxShowPageBox
      this.nowPageNum = this.morePageMid + 1
      if (!noRepeatTrigger) this.$emit('changePageNum', this.nowPageNum)

    },
    changePageSize (e) { //改变页码
      this.nowPageNum = 1
      this.morePageMid = 0
      this.usePageSize = e.target.value
      this.$emit('changePageSize', this.usePageSize)
    },
    inputChangePageSize (e) { //输入框跳转指定页码
      // if (e.target.value > this.totalPage) {
      //   return e.target.value = ''
      // } else {
      //   this.nowPageNum = e.target.value
      //   if (this.nowPageNum > this.maxShowPageBox + this.morePageMid) {
      //     this.morePageMid += this.maxShowPageBox
      //   }
      //   else if (this.morePageMid !== 0) {
      //     this.morePageMid -= this.maxShowPageBox
      //   }
      //   e.target.value = ''
      // }
      // this.$emit('changePageNum', this.nowPageNum)

      if (e.target.value > this.totalPage) {
        return e.target.value = ''
      } else {
        if (!e.target.value) {
          e.target.value = this.nowPageNum
        } else if (e.target.value < 1) {
          e.target.value = 1
        }
        this.nowPageNum = e.target.value
        /* 跳转到当前页 前后  morePageMid不用变 只需要变nowPageNum */
        /* 跳转到非当前页 1.非当前页的后面 2.非当前页的前面*/

        if (this.nowPageNum > this.maxShowPageBox + this.morePageMid) {//4 > 0 + 8  50 => 56 mid48  56 > 8 + 48 当前页不执行   跳转到后面的页面
          this.morePageMid = Math.ceil(this.nowPageNum / this.maxShowPageBox) * this.maxShowPageBox - this.maxShowPageBox
        } else if (this.nowPageNum < (this.maxShowPageBox + this.morePageMid) && this.morePageMid !== 0) {//前往到后面页面  返回到前面
          //第二页  12 => 15  15 < 8 +8 = 16
          //第三页  20 => 2   100 => 2
          // this.morePageMid -= this.maxShowPageBox
          this.morePageMid = Math.ceil(this.nowPageNum / this.maxShowPageBox) * this.maxShowPageBox - this.maxShowPageBox
        }
        // e.target.value = ''
      }
      this.$emit('changePageNum', this.nowPageNum)
    }
  },
  computed: {
    showEndGroup () {
      if (this.morePageMid * 2 < this.totalPage) {
        return true
      } else {
        if ((this.totalPage - this.morePageMid) > this.maxShowPageCard) {
          return true
        } else {
          return false
        }
      }
    },
    prevDefaultStyle () { //上一页按钮额外样式
      if (this.nowPageNum == 1) {
        return 'cursor:no-drop'
      }
    },
    nextDefaultStyle () { //下一页按钮额外样式
      if (this.nowPageNum == this.totalPage) {
        return 'cursor:no-drop'
      }
    },
    totalPage () { //总页数
      return Math.ceil(this.total / this.usePageSize)
    },
    showMaxPage () { //每页显示的页盒子数
      if (this.morePageMid * 2 > this.totalPage) {//this.totalPage > this.maxShowPageCard  125 > 8
        if ((this.totalPage - this.morePageMid) > this.maxShowPageCard) {
          return this.maxShowPageCard
        } else {
          return this.totalPage - this.morePageMid
        }
      }
      if (this.totalPage < this.maxShowPageCard) {
        return this.totalPage
      }
      // 初始化的时候返回 0*2 < this.totalPage  0 < 125   morePageMid 是62 之前都是走这里
      return this.maxShowPageCard
    }
  },
}
</script>

<style scoped>
.pragination {
}
i {
  font-style: normal;
  font-size: 13px;
}
.active {
  color: rgb(95, 110, 247);
}
span,
.el-icon-arrow-left,
.el-icon-arrow-right {
  cursor: pointer;
  margin: 0 10px;
}
span:hover {
  color: rgb(95, 110, 247);
}
.el-icon-arrow-left:hover,
.el-icon-arrow-right:hover {
  color: rgb(95, 110, 247);
}
select {
  outline: none;
}
.inputChangePageSize {
  outline: none;
  width: 40px;
  border-radius: 15px;
  border: 2px solid #ccc;
  transition: 0.2s linear;
}
.inputChangePageSize:focus {
  border-color: rgb(117, 156, 206);
}
</style>