113 lines
2.7 KiB
Vue
113 lines
2.7 KiB
Vue
<template>
|
|
<view class="pagination">
|
|
<text :disabled="page <= 1" @tap.stop="gotoPage(page - 1)"><</text>
|
|
<text v-for="item in pages" :key="getItemKey(item)" :class="{ active: item === page, ellipsis: item === '...' }" @tap.stop="gotoPage(item)">{{ item }}</text>
|
|
<text :disabled="page >= totalPages" @tap.stop="gotoPage(page + 1)">></text>
|
|
<text class="page_txt mgl10">跳转到</text>
|
|
<input type="number" class="page_input" v-model="val" @blur.stop="inputPage">
|
|
<text class="page_txt">页</text>
|
|
</view>
|
|
</template>
|
|
|
|
<script>
|
|
export default {
|
|
name: 'Pagination',
|
|
data () {
|
|
return {
|
|
val: ''
|
|
}
|
|
},
|
|
props: {
|
|
total: { // 总条目数
|
|
type: Number,
|
|
required: true
|
|
},
|
|
pageSize: { // 每页显示的条目数
|
|
type: Number,
|
|
default: 10
|
|
},
|
|
currentPage: { // 当前页码
|
|
type: Number,
|
|
default: 1
|
|
}
|
|
},
|
|
computed: {
|
|
totalPages() { // 总页数
|
|
return Math.ceil(this.total / this.pageSize)
|
|
},
|
|
page() { // 当前页码,限定在 1 和总页数之间
|
|
return Math.max(1, Math.min(this.currentPage, this.totalPages))
|
|
},
|
|
pages() { // 可点击的页码数组,最多显示 5 个页码
|
|
const arr = []
|
|
let start = Math.max(this.page - 2, 1)
|
|
let end = Math.min(start + 4, this.totalPages)
|
|
if (end - start < 4) {
|
|
end = Math.min(start + 4, this.totalPages)
|
|
start = Math.max(end - 4, 1)
|
|
}
|
|
for (let i = start; i <= end; i++) {
|
|
arr.push(i)
|
|
}
|
|
if (end < this.totalPages) {
|
|
arr.push('...', this.totalPages)
|
|
}
|
|
return arr
|
|
}
|
|
},
|
|
methods: {
|
|
getItemKey(item) { // 获取项的 key
|
|
return typeof item === 'number' ? item.toString() : item
|
|
},
|
|
gotoPage(page) { // 跳转到指定页码
|
|
if (page > 0 && page <= this.totalPages) {
|
|
this.$emit('page-change', page)
|
|
}
|
|
},
|
|
inputPage() { // 跳转到指定页码
|
|
const numericValue = Number(this.val)
|
|
if (numericValue > 0 && numericValue <= this.totalPages) {
|
|
this.$emit('page-change', numericValue)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<style lang="stylus" scoped>
|
|
@import '@/common/style/mixin.styl';
|
|
.pagination {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
// padding: 20px 0;
|
|
}
|
|
text,.page_input {
|
|
display: inline-block;
|
|
padding: 0 10px;
|
|
background: linear-gradient(180deg, #0E284B, #2D70A3);
|
|
border: 1px solid #3274CD;
|
|
border-radius: 3px;
|
|
margin-right: 10px;
|
|
_font(13px, 26px, #fff,,)
|
|
}
|
|
|
|
text.active {
|
|
background: linear-gradient(180deg, #2160D2, #3688DE);
|
|
color: #fff;
|
|
}
|
|
|
|
text.ellipsis {
|
|
cursor: default;
|
|
}
|
|
.page_input {
|
|
width: 50px
|
|
height: 28px;
|
|
text-align: center;
|
|
}
|
|
.page_txt {
|
|
}
|
|
.mgl10 {
|
|
margin-left: 20px
|
|
}
|
|
</style> |