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、成果