組件效果圖
組件用法
<pagination
:show-jumper="true"
:total="100"
:currentPage="20"
:pagerCount="7"
@prev-click="prevClick"
@next-click="nextClick"
@prev-quick-click="prevQuickClick"
@next-quick-click="nextQuickClick"
@page-click="pageClick"
@current-change="currentChange"
@jumpe="pageJumpe"
/>
<script>
methods: {
prevClick(page) {
console.log('上一頁', page);
},
nextClick(page) {
console.log('下一頁', page);
},
pageClick(page) {
console.log('分頁點擊', page);
},
pageJumpe(page) {
console.log('跳轉', page);
},
prevQuickClick(page) {
console.log('快速向前切換', page);
},
nextQuickClick(page) {
console.log('快速向後切換', page);
},
currentChange(page, old) {
console.log('分頁切換', page, '切換前分頁', old);
}
}
</script>
組件代碼
<template>
<div class="pagination" :class="{' pagination-vertical' : mode ==='vertical'}">
<button type="button" :disabled="current === 1" class="btn-prev" @click="prevPage">
<i class="iconfont icon-arrow-left"></i>
</button>
<ul class="pager">
<li
v-for="(page, index) in pageList"
:class="{
active: page === current && typeof page !== 'string',
'more btn-quickprev': page === 'prev',
'more btn-quicknext': page === 'next'
}"
@click="pagerClick(page)"
>{{typeof page === 'number' ? page + suffix : '•••'}}</li>
</ul>
<button type="button" :disabled="current === total" class="btn-next" @click="nextPage">
<i class="iconfont icon-arrow-right"></i>
</button>
<span class="go-page" v-if="showJumper && mode ==='horizontal'">
前往 
<input
ref="goPageInput"
type="text"
@blur="goPage($refs.goPageInput.value*1)"
/> 頁
</span>
</div>
</template>
<script>
export default {
name: 'pagination',
props: {
total: {
type: Number,
default: 30
},
currentPage: {
type: Number,
default: 1
},
pagerCount: {
type: Number,
default: 7
},
mode: {
type: String,
default: 'horizontal'
},
showJumper: {
type: Boolean,
default: false
},
suffix: {
type: String,
default: ''
}
},
data() {
return {
current: 1,
pageList: []
};
},
watch: {
total() {
this.getPageList(this.current);
},
currentPage(val) {
this.current = val;
},
pagerCount() {
this.getPageList(this.current);
},
current(val, old) {
this.pageList = this.getPageList(val);
this.$emit('current-change', val, old);
}
},
mounted() {
this.current = this.currentPage;
this.pageList = this.getPageList(this.current);
},
methods: {
getPageList(current) {
let { total, pagerCount } = this;
let pageList = [];
if (pagerCount > total - 1) {
for (let i = 1; i <= total; i++) {
pageList.push(i);
}
} else {
if (current < pagerCount - 1) {
for (let i = 1; i < pagerCount; i++) {
pageList.push(i);
}
pageList.push('next');
pageList.push(total);
} else {
if (current >= total - 1 - Math.floor(pagerCount / 2)) {
pageList.push(1);
pageList.push('prev');
for (
let i = total - (pagerCount - 2);
i <= total;
i++
) {
pageList.push(i);
}
} else {
pageList.push(1);
pageList.push('prev');
for (
let i = current - Math.floor((pagerCount - 2) / 2);
i <=
current + (Math.ceil((pagerCount - 2) / 2) - 1);
i++
) {
pageList.push(i);
}
pageList.push('next');
pageList.push(total);
}
}
}
return pageList;
},
prevPage() {
if (this.current > 1) {
this.current--;
this.$emit('prev-click', this.current);
}
},
nextPage() {
if (this.current < this.total) {
this.current++;
this.$emit('next-click', this.current);
}
},
pagerClick(page) {
if (typeof page === 'number') {
this.current = page;
this.$emit('page-click', page);
} else {
let quickPage = 1;
if (page === 'prev') {
quickPage = this.current - (this.pagerCount - 2);
quickPage < 1 && (quickPage = 1);
}
if (page === 'next') {
quickPage = this.current + (this.pagerCount - 2);
quickPage > this.total && (quickPage = this.total);
}
this.current = quickPage;
this.$emit(`${page}-quick-click`, this.current);
}
},
goPage(page) {
this.current = page < 1 ? 1 : page > this.total ? this.total : page;
this.$refs.goPageInput.value = this.current;
this.$emit('jumpe', page);
}
}
};
</script>
<style lang="scss" scoped>
.pagination {
&,
& * {
box-sizing: border-box;
}
display: flex;
min-height: 32px;
border-radius: 2px;
background-color: #fff;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);
.pager {
display: flex;
margin: 0;
padding: 0;
li {
list-style: none;
color: #606266;
&:not(.disabled).active {
color: #fff;
background-color: #409eff;
pointer-events: none;
cursor: none;
}
&:hover {
color: #409eff;
}
}
.more {
color: #999;
}
}
.pager li,
.btn-next,
.btn-prev {
min-width: 32px;
height: 32px;
line-height: 32px;
font-size: 12px;
text-align: center;
background-color: #fff;
cursor: pointer;
user-select: none;
}
button {
display: block;
border: 0;
font-weight: 600;
color: #888;
vertical-align: top;
&:focus {
outline: none;
border: none;
}
&[disabled] {
color: #c0c4cc;
cursor: not-allowed;
}
}
.btn-prev {
border-bottom-left-radius: 2px;
border-bottom-right-radius: 2px;
}
.btn-next {
border-top-left-radius: 2px;
border-top-right-radius: 2px;
}
.go-page {
height: 32px;
line-height: 32px;
font-size: 12px;
margin-right: 10px;
input {
width: 40px;
height: 22px;
line-height: 20px;
border: 1px solid #ddd;
border-radius: 4px;
color: #606266;
text-align: center;
&:focus {
outline: none;
}
}
}
}
.pagination-vertical {
flex-direction: column-reverse;
.pager {
flex-direction: column-reverse;
}
button {
transform: rotate(-90deg);
}
.btn-prev {
border-top-left-radius: 2px;
border-bottom-right-radius: 0;
}
.btn-next {
border-top-left-radius: 0;
border-bottom-right-radius: 2px;
}
}
</style>