使用vue打造分页器

250 阅读1分钟

   在学习vue的过程中,看到各种UI框架都带有分页器,我就也想搞一个,这次做的是根据后台返回的页数,进行分页查询的效果。借鉴了Ant-Desgin-vue的风格。

   效果如下:

<template>
  <div class="Pagination">
    <div class="prev Pagination-box" :class="CurrentIndex<=1?'disable':''" @click="prev">
      <svg
        viewBox="64 64 896 896"
        data-icon="left"
        width="1em"
        height="1em"
        fill="currentColor"
        aria-hidden="true"
        focusable="false"
        class
      >
        <path
          d="M724 218.3V141c0-6.7-7.7-10.4-12.9-6.3L260.3 486.8a31.86 31.86 0 0 0 0 50.3l450.8 352.1c5.3 4.1 12.9.4 12.9-6.3v-77.3c0-4.9-2.3-9.6-6.1-12.6l-360-281 360-281.1c3.8-3 6.1-7.7 6.1-12.6z"
        />
      </svg>
    </div>
    <div class="Pagination-box" :class="1==CurrentIndex?'select':''" @click="select(1)">1</div>
    <div class="Pagination-box" v-if="(CurrentIndex-1)>2" @click="doubleS(-2)">...</div>
    <div
      class="Pagination-box"
      :class="item==CurrentIndex?'select':''"
      v-for="item in getTotal"
      :key="item"
      @click="select(item)"
    >{{item}}</div>
    <div class="Pagination-box" v-if="(TotalNumber-CurrentIndex)>2" @click="doubleS(2)">...</div>
    <div
      class="Pagination-box"
      :class="TotalNumber==CurrentIndex?'select':''"
      @click="select(TotalNumber)"
    >{{TotalNumber}}</div>
    <div class="next Pagination-box" :class="CurrentIndex>=TotalNumber?'disable':''" @click="next">
      <svg
        viewBox="64 64 896 896"
        data-icon="right"
        width="1em"
        height="1em"
        fill="currentColor"
        aria-hidden="true"
        focusable="false"
        class
      >
        <path
          d="M765.7 486.8L314.9 134.7A7.97 7.97 0 0 0 302 141v77.3c0 4.9 2.3 9.6 6.1 12.6l360 281.1-360 281.1c-3.9 3-6.1 7.7-6.1 12.6V883c0 6.7 7.7 10.4 12.9 6.3l450.8-352.1a31.96 31.96 0 0 0 0-50.4z"
        />
      </svg>
    </div>
    <div class="totalPage">共 {{TotalNumber}} 页</div>
  </div>
</template>
<script>
export default {
  props: ["TotalNumber"],
  data() {
    return {
      result: [],
      CurrentIndex: 1,
    };
  },
  computed: {
    getTotal() {
      return this.result.filter((res) => {
        return (
          Math.abs(res - this.CurrentIndex) < 2 &&
          res != this.TotalNumber &&
          res != 1
        );
      });
    },
  },
  methods: {
    select(item) {
      this.CurrentIndex = item;
    },
    prev() {
      if (this.CurrentIndex > 1) this.CurrentIndex--;
    },
    next() {
      if (this.CurrentIndex < this.TotalNumber) this.CurrentIndex++;
    },
    doubleS(item) {
      console.log(this.result, item);
      if (item < 0) {
        this.CurrentIndex -= 2;
      } else {
        this.CurrentIndex += 2;
      }
    },
  },
  watch: {
    CurrentIndex() {
      this.$emit("selectClick", this.CurrentIndex);
    },
    TotalNumber(newVal) {
      this.TotalNumber = newVal;
      for (let i = 1; i <= this.TotalNumber; i++) {
        this.result.push(i);
      }
    },
  },
};
</script>
<style lang="less" scoped>
.Pagination {
  display: flex;
  .Pagination-box {
    width: 32px;
    height: 32px;
    border: 1px solid #cccccc;
    border-radius: 2px;
    display: inline-block;
    vertical-align: middle;
    line-height: 32px;
    text-align: center;
    margin-right: 8px;
    transition: all 0.3s;
    cursor: pointer;
    svg {
      width: 12px;
      height: 12px;
    }
  }
  .select {
    border: 1px solid #3399ff;
    color: #3399ff;
  }
  .disable {
    opacity: 0.5;
    cursor: not-allowed;
  }
}
.totalPage {
  font-size: 14px;
  text-align: center;
  height: 32px;
  line-height: 32px;
}
</style>