1. 程式人生 > >JS簡易分頁頁碼演算法

JS簡易分頁頁碼演算法

BUG未知 ...

function getRangeArray(start, end) {
  if (start > end) throw('');
  const RANGE = end - start;
  const result = Array.apply(null, {length: RANGE});
  for (let i = 0; i <= RANGE; i++) {
    result[i] = i + start;
  }
  return result;
}

function getPageRangeArray(page = 1, size = 10, total, MAX_SHOW_PAGE_NUMBER = 4) {
  /**
   * 大致四種情況
   * [1,2,3,4]
   * [1,2,3,'...',5]
   * [1,'...',4,5,6,'...'12]
   * [1,'...',3,4,5]
   * */
  if (MAX_SHOW_PAGE_NUMBER < 4) throw('');
  if (!total) throw('');
  const TOTAL_PAGE = Math.ceil(total / size);
  if (page > TOTAL_PAGE) throw('');
  //main
  //頁數太少時
  if (TOTAL_PAGE <= MAX_SHOW_PAGE_NUMBER) return getRangeArray(1, TOTAL_PAGE);
  if (page < MAX_SHOW_PAGE_NUMBER) {
    return [...getRangeArray(1, MAX_SHOW_PAGE_NUMBER), '...', TOTAL_PAGE];
  } else if (TOTAL_PAGE - page >= MAX_SHOW_PAGE_NUMBER) {
    const pivot = Math.ceil(MAX_SHOW_PAGE_NUMBER / 2);
    return ['1', '...', ...getRangeArray(page - pivot, page - 1), page, ...getRangeArray(page + 1, page + pivot), '...', TOTAL_PAGE];
  } else {
    return ['1', '...', ...getRangeArray(TOTAL_PAGE - MAX_SHOW_PAGE_NUMBER, TOTAL_PAGE)];
  }
}

console.log(getPageRangeArray(12, 5, 100));
console.log(getPageRangeArray(3, 5, 20));
console.log(getPageRangeArray(9, 10, 86));
<template>
  <div class="zj_page clearfix">
    <div class="float-left" :class="{disabled:cPage === 1}">
      <span class="options" @click="change_page(1)">首頁</span>
      <span class="options" @click="change_page(cPage - 1)">上一頁</span>
    </div>
    <ul class="float-left pages">
      {{cPage === 1 || cPage === totalPage}}
      <li v-for="(item,index) in page_range" :key="index" @click="change_page(item)"
          :class="{active:item === cPage}">{{item}}
      </li>
    </ul>
    <div class="float-left" :class="{disabled:cPage === totalPage}">
      <span class="options" @click="change_page(cPage + 1)">下一頁</span>
      <span class="options" @click="change_page(totalPage)">尾頁</span>
    </div>
  </div>
</template>

<script>
  //沒時間做, 只顯示5頁
  export default {
    props: {
      page: {
        type: Number,
      },
      size: {
        type: Number,
      },
      total: {
        type: Number,
      },
    },
    data() {
      return {
        cPage: this.page,
        totalPage: Math.ceil(this.total / this.size),
      };
    },
    methods: {
      change_page(p) {
        if (p === '...') return;
        this.$emit('on-page-change', this.cPage = p);
      },
      getRangeArray(start, end) {
        if (start > end) throw('');
        const RANGE = end - start;
        const result = Array.apply(null, {length: RANGE});
        for (let i = 0; i <= RANGE; i++) {
          result[i] = i + start;
        }
        return result;
      },
    },
    computed: {
      page_range() {
        //MAX_SHOW_PAGE_NUMBER >= 4
        const MAX_SHOW_PAGE_NUMBER = 7,
          TOTAL_PAGE = this.totalPage = Math.ceil(this.total / this.size);
        //頁數太少時
        if (TOTAL_PAGE <= MAX_SHOW_PAGE_NUMBER) return this.getRangeArray(1, TOTAL_PAGE);
        if (this.cPage < MAX_SHOW_PAGE_NUMBER) {
          return [...this.getRangeArray(1, MAX_SHOW_PAGE_NUMBER), '...', TOTAL_PAGE];
        }
        else if (TOTAL_PAGE - this.cPage >= MAX_SHOW_PAGE_NUMBER) {
          const pivot = Math.ceil(MAX_SHOW_PAGE_NUMBER / 2);
          return ['1', '...',
            ...this.getRangeArray(this.cPage - pivot, this.cPage - 1),
            this.cPage,
            ...this.getRangeArray(this.cPage + 1, this.cPage + pivot),
            '...', TOTAL_PAGE];
        }
        else {
          return ['1', '...', ...this.getRangeArray(TOTAL_PAGE - MAX_SHOW_PAGE_NUMBER, TOTAL_PAGE)];
        }
      },
    },
  };
</script>

<style scoped lang="less">
  .zj_page {
    font-size: 14px;
    line-height: 30px;
    .disabled {
      .options {
        color: #C8CDD2;
        pointer-events: none;
      }
    }
    .options {
      margin-right: 10px;
      cursor: pointer;
    }
    .pages {
      height: 30px;
      margin-right: 10px;
      font-size: 0;
      li {
        display: inline-block;
        width: 30px;
        height: 30px;
        border-radius: 50%;
        text-align: center;
        font-size: 14px;
        cursor: pointer;
        &.active {
          color: #fff;
          background-color: #888;
        }
      }
    }
  }
</style>