![8294f916e0e8aece6b175132a1f919a3.png](https://img-blog.csdnimg.cn/img_convert/8294f916e0e8aece6b175132a1f919a3.png)
因为要给表格分页添加一些小功能,但是现成的UI库分页组件没有提供这些细节,于是只有自己动手写。记得上次写分页功能已经是好几年前了,还是用jQuery写的。刚开始以为很简单,但其实写还有点小难度,当前页码为1时直接输出其它页码就好,但是当页码大于1,大于总页码减5时,均要使用不同的判断,总共用时三个小时,记录一下。
首先简单整理了一下需求:
- 1、页码最多显示5个。
- 2、提供上一页、下一页、首页、尾页功能。
- 3、显示当前页、数据总条数。
- 4、支持改变每页显示数据的数量。
- 5、显示当前页临近的4页。
- 6、兼容以前的代码。
<template>
<div>
<div class="wrap">
<a-row>
<a-col :span="8">
<div class="page-info">
共 {{ total }} 条记录,第 {{ current }} / {{ totalPage }} 页
</div>
</a-col>
<a-col :span="16">
<ul>
<li>
<a @click="handleClick('first')" :class="firstDisabled ? 'disabled' : ''"><a-icon type="double-left" /></a>
</li>
<li>
<a @click="handleClick('prev')" :class="prevDisabled ? 'disabled' : ''"><a-icon type="left" /></a>
</li>
<li :total="total" :value="index" v-for="(item, index) in data" :key="index">
<a @click="handleClick(item.number)" :class="current === item.number ? 'current' : ''">{{ item.number }}</a>
</li>
<li>
<a @click="handleClick('next')" :class="nextDisabled ? 'disabled' : ''"><a-icon type="right" /></a>
</li>
<li>
<a @click="handleClick('end')" :class="endDisabled ? 'disabled' : ''"><a-icon type="double-right" /></a>
</li>
<li>
<a-select :default-value="defaultPageSize" style="width: 120px" size="large" @change="handlePageChang">
<a-select-option :value="item" :key="index" v-for="(item, index) in pageSize">{{ item }} 条/页</a-select-option>
</a-select>
</li>
</ul>
</a-col>
</a-row>
</div>
</div>
</template>
<script>
export default {
name: 'Pagination',
data () {
return {
data: [],
totalPage: 1,
defaultPageSize: 10,
pageSize: [10, 20, 30, 40, 50]
}
},
mounted () {
// console.log(this.pagination)
},
methods: {
handlePageChang (val) {
// pageSize表示当前页显示的数据条数
this.$emit('change', { 'pageSize': Number(val) })
},
handleClick (val) {
// pageNo表示当前页
switch (val) {
case 'prev':
if (!this.prevDisabled) {
this.$emit('change', { 'pageNo': this.current - 1 })
}
break
case 'next':
if (!this.nextDisabled) {
this.$emit('change', { 'pageNo': this.current + 1 })
}
break
case 'first':
if (!this.firstDisabled) {
this.$emit('change', { 'pageNo': 1 })
}
break
case 'end':
if (!this.endDisabled) {
this.$emit('change', { 'pageNo': this.totalPage })
}
break
default:
this.$emit('change', { 'pageNo': val })
break
}
}
},
watch: {
'pagination.total': {
handler () {
this.totalPage = Math.ceil(this.total / 10)
const arr = []
const lth = this.totalPage > 5 ? 5 : this.totalPage
console.log(this.current + '+' + this.totalPage)
if (this.current === 1) {
// 页码为1时单独处理
for (let i = 0; i < lth - this.current + 1; i++) {
arr.push({
number: this.current + i
})
}
} else if (this.current > 1) {
if (this.totalPage > 6) {
// 页码总数大于6时单独处理
if (this.current > this.totalPage - 5) {
// 当前页大于页码总数减5时单独处理
for (let i = this.totalPage; i !== (this.totalPage - 5); i--) {
arr.unshift({
number: i
})
}
} else {
for (let i = 0; i < 5; i++) {
arr.push({
number: this.current + i
})
}
}
} else {
for (let i = this.totalPage; i !== (this.totalPage > 5 ? this.totalPage - 5 : 0); i--) {
arr.unshift({
number: i
})
}
}
}
this.data = arr
},
immediate: true,
deep: true
}
},
computed: {
prevDisabled () {
return this.current === 1
},
nextDisabled () {
return this.current === this.totalPage
},
firstDisabled () {
return this.current === 1
},
endDisabled () {
return this.current === this.totalPage
},
current () {
return this.pagination.current || 1
},
total () {
return this.pagination.total || 0
}
},
props: {
pagination: {
type: Object,
default: () => {
return {}
}
}
}
}
</script>
<style lang="less" scoped>
.wrap {
clear: both;
overflow: hidden;
padding: 30px 0;
/deep/.ant-select-selection-selected-value {
color: #666;
}
.page-info {
color: #666;
line-height: 30px;
}
ul {
list-style: none;
margin: 0;
padding: 0;
float: right;
li {
padding: 0 0 10px 6px;
margin: 0;
display: inline-block;
a {
padding: 8px 0;
border: 1px solid #ddd;
display: block;
min-width: 34px;
text-align: center;
border-radius: 4px;
color: #333;
&:hover {
border-color: #08c;
color: #08c;
}
&.current {
border-color: #08c;
color: #fff;
background: #08c;
}
&.disabled {
color: #aaa;
border-color: #eee;
cursor: not-allowed;
}
}
}
}
}
</style>