all files / src/pager/ pager.vue

100% Statements 13/13
88.89% Branches 8/9
100% Functions 8/8
100% Lines 12/12
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132                                                      35×   26×                                                           49× 54×   26× 26×     26×                                                                                                                        
<template>
  <div class="am-pager" :class="{hide:hideOnSinglePage===true &&totalPage<=1}">
    <span class="am-pager-item prev" @click="goPage(currentPage-1)" :class="{disabled:currentPage===1}">
      <am-icon name="left"></am-icon>
    </span>
    <template v-for="(page,index) in pages">
      <template v-if="page===currentPage">
        <span class="am-pager-item active" :data-current="page" @click="goPage(page)">{{page}}</span>
      </template>
      <template v-else-if="page==='...'">
        <span class="am-pager-item separator">
          <am-icon name="ellipsis"></am-icon>
        </span>
      </template>
      <template v-else>
        <span class="am-pager-item other" :data-page="page" @click="goPage(page)">{{page}}</span>
      </template>
    </template>
    <span class="am-pager-item next" @click="goPage(currentPage+1)" :class="{disabled:currentPage===totalPage}">
      <am-icon name="right"></am-icon>
    </span>
  </div>
</template>
 
<script>
import AmIcon from "../icon";
function unique(arr) {
  let obj = {};
  arr.forEach(item => {
    obj[item] = true;
  });
  return Object.keys(obj).map(a => parseInt(a, 10));
}
export default {
  name: "amPagination",
  components: { AmIcon },
  props: {
    currentPage: {
      type: Number,
      required: true
    },
    totalPage: {
      type: Number,
      required: true
    },
    hideOnSinglePage: {
      type: Boolean,
      default: true
    }
  },
  computed: {
    pages() {
      return unique(
        [
          1,
          this.currentPage,
          this.totalPage,
          this.currentPage - 1,
          this.currentPage - 2,
          this.currentPage + 1,
          this.currentPage + 2
        ]
          .filter(a => a >= 1 && a <= this.totalPage)
          .sort((a, b) => a - b)
      ).reduce((prev, current, index, array) => {
        prev.push(current);
        array[index + 1] !== undefined &&
          array[index + 1] - array[index] > 1 &&
          prev.push("...");
        return prev;
      }, []);
    }
  },
  methods: {
    goPage(n) {
      Eif (n >= 1 && n <= this.totalPage) {
        this.$emit("update:currentPage", n);
      }
    }
  }
};
</script>
 
<style lang="scss" scoped>
@import "var";
.am-pager {
  $font-size: 14px;
  $width: 22px;
  $height: 28px;
  display: flex;
  justify-content: flex-start;
  align-items: center;
  &.hide {
    display: none;
  }
  &-item {
    display: inline-flex;
    justify-content: center;
    align-items: center;
    padding: 0 4px;
    font-size: $font-size;
    text-align: center;
    color: $color;
    min-width: $width;
    height: $height;
    margin: 0 4px;
    border-radius: $border-radius;
    border: 1px solid $border-color;
    cursor: pointer;
    user-select: none;
    transition: all 0.25s;
    &.separator {
      border: none;
    }
    &.active,
    &:hover {
      border-color: $blue;
    }
    &.disabled {
      border-color: darken($gray, 10%);
      cursor: not-allowed;
      &:hover {
        border-color: $gray;
      }
      svg {
        fill: darken($gray, 30%);
      }
    }
  }
}
</style>