示例
Events
事件名称 | 说明 | 回调参数 |
---|
current-change | current-change currentPage 改变时会触发 当前页 | 当前页 |
prev-click | 用户点击上一页按钮改变当前页后触发 | 当前页 |
next-click | 用户点击下一页按钮改变当前页后触发 | 当前页 |
Attributes
参数 | 说明 | 类型 | 可选值 | 默认值 |
---|
total | 总条数 | Number | - | 0 |
currentPage | 当前页数 需添加.sync修饰符 | Number | - | 1 |
pageSize | 每页显示条目个数 | Number | - | 10 |
pageCount | 页码按钮的数量,当总页数超过该值时会折叠 | Number | 大于等于 5 且小于等于 21 的奇数 | 7 |
页面代码
<template>
<div class="Pagination">
<button class="Pagination__item Pagination__button" :class="page === 1 ? 'disable' : ''" @click="prevClick">
<span>{{leftIcon}}</span>
</button>
<div class="Pagination__ul">
<div class="Pagination__item Pagination__li" :class="page === 1 ? 'action-current' : ''" @click="handlePage(1)">1</div>
<div v-if="page - nums - 1 > 1 && totalPage > pageCount" class="Pagination__item Pagination__li" @click="prevEllipsisClick">...</div>
<div v-for="item in pageList" :key="item">
<div
class="Pagination__item Pagination__li"
:class="item === page ? 'action-current' : ''"
@click="handlePage(item)"
>{{item}}</div>
</div>
<div v-if="page + nums + 1 < totalPage && totalPage > pageCount" class="Pagination__item Pagination__li" @click="nextEllipsisClick">...</div>
<div class="Pagination__item Pagination__li" :class="page === totalPage ? 'action-current' : ''" @click="handlePage(totalPage)">{{totalPage}}</div>
</div>
<button class="Pagination__item Pagination__button" :class="page === totalPage ? 'disable' : ''" @click="nextClick">
<span>{{rightIcon}}</span>
</button>
<div class="Pagination__input">
<span>前往</span>
<div class="p-input" :class="ifFocus ? 'focus' : ''">
<input type="text" class="input" v-model="inputValue" @change="inputChange" @blur="ifFocus = false" @focus="ifFocus = true">
</div>
<span>页</span>
</div>
</div>
</template>
js代码
export default {
name: 'pagination',
data() {
return {
leftIcon: '<',
rightIcon: '>',
page: 1,
size: 10,
inputValue: '',
ifFocus: false,
}
},
computed: {
totalPage() {
console.log(Math.ceil(this.total / this.pageSize), this.pageCount);
return Math.ceil(this.total / this.pageSize);
},
nums() {
return Math.floor((this.pageCount - 3) / 2)
},
pageList() {
const listTotal = this.totalPage;
let count = this.pageCount;
let list = [];
const num = this.nums
if (listTotal <= count) {
for (let i = 0; i < listTotal - 2; i++) {
list.push(i + 2);
}
} else {
if ((this.page - num - 1) <= 1) {
for (let i = 0; i < count - num ; i++) {
list[i] = i + 2;
}
} else if ((this.page + num + 1) >= listTotal) {
for (let i = 0; i < count - num; i++) {
list[i] = listTotal - (count -num - i);
}
} else {
for (let i = 0; i < num; i++) {
list[i] = this.page - (num - i);
}
list[num] = this.page;
for (let i = 0; i < num; i++) {
list[num + 1 + i] = this.page + i + 1;
}
}
}
console.log(list);
return list
},
pageCountFloor() {
return Math.floor(this.pageCount / 2)
}
},
watch: {
currentPage(newValue) {
if (newValue !== this.page) this.page = newValue;
},
page(newValue) {
if (newValue !== this.inputValue) this.inputValue = newValue;
},
},
created() {
if (this.currentPage !== this.page) this.page = this.currentPage;
if (this.page !== this.inputValue) this.inputValue = this.page;
},
methods: {
handlePage(item) {
if (item === this.page) return
this.page = item;
this.$emit('update:currentPage', item);
this.$emit('current-change', item);
},
inputChange(e) {
const value = Number(e.target.value);
if (value !== 'NaN' && this.$utils.strType(value) === 'Number') {
if (value > 0 && value <= this.totalPage) {
this.handlePage(value)
} else this.inputValue = this.page;
} else this.inputValue = this.page;
},
prevClick() {
if (this.page === 1) return
this.handlePage(this.page - 1)
},
nextClick() {
if (this.page === this.totalPage) return
this.handlePage(this.page + 1)
},
nextEllipsisClick() {
if (this.page === 1) this.handlePage(this.page + this.nums + 2);
else this.handlePage(this.page + this.nums);
},
prevEllipsisClick() {
console.log(this.nums);
if (this.page === this.totalPage) this.handlePage(this.page - this.nums - 2);
else this.handlePage(this.page - this.nums);
},
}
}
样式代码
<style lang="scss" scoped>
ul, li, ol {
list-style: none;
margin: 0;
padding: 0;
}
.Pagination {
display: flex;
align-items: center;
font-size: 16px;
&__item {
padding: 0 12px;
cursor: default;
&:hover {
color: #409eff;
}
&.action-current {
color: #409eff;
}
}
&__button {
color: #606266;
background: transparent;
border: none;
outline: none;
}
&__ul {
display: flex;
align-items: center;
}
&__input {
display: flex;
align-items: center;
.p-input {
width: 50px;
line-height: 18px;
height: 28px;
text-align: center;
box-sizing: border-box;
border-radius: 3px;
border: 1px solid #dcdfe6;
background-color: #fff;
margin: 0 2px;
padding: 0 2px;
&.focus {
border-color: #409eff;
}
.input {
border: none;
width: 100%;
height: 100%;
background-image: none;
border-radius: 4px;
padding: 0;
text-align: center;
outline:none;
&:focus {
border: none;
}
}
}
}
.disable {
color: #c0c4cc !important;
cursor: no-drop !important;
}
.disable-button {
background: #f4f4f5;
cursor: no-drop !important;
}
}
</style>