乐趣区

关于前端:Nuxtjs手写一个分页组件

1、HTML && CSS

@/components/Paginationn.vue

<template>
  <div v-if="totalCount" class="page-wrap">
    <span v-if="currentPage != 1" class="li-page" @click="goPrePage">
      上一页
    </span>
    <ul>
      <li
        v-for="(i, index) in showPageBtn"
        :key="index"
        :class="{active: i === currentPage}"
        @click="pageOffset(i)"
      >
        <span v-if="i">{{i}}</span>
        <span v-else>···</span>
      </li>
    </ul>
    <span v-if="totalCount > limit" class="li-page" @click="goNextPage">
      下一页
    </span>
  </div>
</template>

<script>
import {mapMutations, mapState} from 'vuex'
export default {
  props: {
    // 数据总数
    totalCount: {
      type: Number,
      default: 0,
    },
    // 每页显示的数据量
    limit: {
      type: Number,
      default: 25,
    },
    // 翻页调用 api 获取数据
    getByPage: {
      type: Function,
      default: () => {},
    },
  },
  data() {return {}
  },
  computed: {...mapState('pagination', ['offset']),
    prePage() {return this.offset !== 0 && this.totalCount},
    nextPage() {return this.offset + this.limit < this.totalCount && this.totalCount},
    totalPage() {return Math.ceil(this.totalCount / this.limit)
    },
    currentPage() {return Math.ceil(this.offset / this.limit) + 1
    },
    showPageBtn() {
      const pageNum = this.totalPage
      const index = this.currentPage
      if (pageNum <= 5) return [...new Array(pageNum)].map((v, i) => i + 1)
      if (index <= 2) return [1, 2, 3, 0, pageNum]
      if (index >= pageNum - 1) return [1, 0, pageNum - 2, pageNum - 1, pageNum]
      if (index === 3) return [1, 2, 3, 4, 0, pageNum]
      if (index === pageNum - 2)
        return [1, 0, pageNum - 3, pageNum - 2, pageNum - 1, pageNum]
      return [1, 0, index - 1, index, index + 1, 0, pageNum]
    },
  },
  created() {const page = Number(this.$route.query.page)
    if (page) {this.GO_PAGE((page - 1) * this.limit)
    }
  },
  methods: {...mapMutations('pagination', ['GO_PAGE', 'PRE_PAGE', 'NEXT_PAGE']),
    pageOffset(i) {if (i === 0 || i === this.currentPage) return
      this.GO_PAGE((i - 1) * this.limit)
      this.getByPage(i)
    },
    goPrePage() {if (this.currentPage >= 2) {this.PRE_PAGE(this.limit)
      }
      if (this.currentPage > 0) this.getByPage(this.currentPage)
    },
    goNextPage() {if (this.currentPage <= this.totalPage) {this.NEXT_PAGE(this.limit)
      }
      if (this.currentPage <= this.totalPage) this.getByPage(this.currentPage)
    },
  },
}
</script>

<style lang="scss" scoped>
.page-wrap {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  text-align: right;
  user-select: none;
  .li-page {
    cursor: pointer;
    width: 65px;
    height: 32px;
    line-height: 32px;
    border: 1px solid rgba(204, 204, 204, 1);
    border-radius: 2px;
    text-align: center;
    margin-left: 12px;
  }
  .li-page:hover {
    color: #fff;
    background: rgba(67, 137, 255, 1);
  }
  ul {
    li {
      position: relative;
      float: left;
      width: 40px;
      height: 32px;
      line-height: 32px;
      font-size: 14px;
      border: 1px solid rgba(204, 204, 204, 1);
      border-radius: 2px;
      text-align: center;
      margin-left: 12px;
      cursor: pointer;
      div {
        position: absolute;
        width: 100%;
        height: 100%;
        z-index: 2;
      }
      a:hover {color: #fff;}
    }
    li:hover,
    li.active {
      color: #fff;
      background: rgba(67, 137, 255, 1);
      a {color: #fff;}
    }
  }
}
</style>

2、Store

@/store/pagination.js

export const state = () => ({offset: 0,})

export const mutations = {
  // 上一页
  PRE_PAGE(state, offset) {state.offset -= offset},
  // 下一页
  NEXT_PAGE(state, offset) {state.offset += offset},
  GO_PAGE(state, offset) {state.offset = offset},
}

3、应用

<template>
  <Pagination 
    :total-count="200"
    :limit="25"
    :get-by-page="getByPage"
  />
</template>

import Pagination from '@/components/Pagination'

export default {
  components: {Pagination,},
  methods:{async getByPage(page) {// 获取第 page 页数据}
  }
}

4、成果

退出移动版