You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
207 lines
4.4 KiB
207 lines
4.4 KiB
<template>
|
|
<div class="pagination flex gap10">
|
|
<!-- 首页按钮 -->
|
|
<GuipButton size="form" v-if="showFirstPage" @click="goToFirstPage" :disabled="currentPage === 1">
|
|
首页
|
|
</GuipButton>
|
|
|
|
<!-- 上一页按钮 -->
|
|
<GuipButton size="form" v-if="showPrevPage" @click="goToPrevPage" :disabled="currentPage === 1">
|
|
上一页
|
|
</GuipButton>
|
|
|
|
<!-- 当前页码 -->
|
|
<span v-if="showCurrentPage">第{{ currentPage }}页</span>
|
|
|
|
<!-- 下一页按钮 -->
|
|
<GuipButton size="form" v-if="showNextPage" @click="goToNextPage" :disabled="!hasNextPage">
|
|
下一页
|
|
</GuipButton>
|
|
|
|
<!-- 尾页按钮 -->
|
|
<GuipButton size="form" v-if="showLastPage" @click="goToLastPage">
|
|
尾页
|
|
</GuipButton>
|
|
|
|
<!-- 跳转输入 -->
|
|
<div class="page-jump flex gap10" v-if="showJump">
|
|
<input type="number" v-model.number="jumpPage" min="1" :max="totalPages">
|
|
<GuipButton size="form" @click="handleJump">跳转</GuipButton>
|
|
</div>
|
|
|
|
<!-- 总记录数 -->
|
|
<span v-if="showTotalRecords" class="total-records">
|
|
共{{ totalRecords }}条记录
|
|
</span>
|
|
</div>
|
|
</template>
|
|
|
|
<script>
|
|
import GuipButton from '@/components/GuipButton.vue';
|
|
|
|
export default {
|
|
name: 'Pagination',
|
|
components: { GuipButton },
|
|
props: {
|
|
// 当前页码
|
|
currentPage: {
|
|
type: Number,
|
|
default: 1
|
|
},
|
|
// 是否有下一页
|
|
hasNextPage: {
|
|
type: Boolean,
|
|
default: false
|
|
},
|
|
// 总记录数
|
|
totalRecords: {
|
|
type: [Number, String],
|
|
default: 0
|
|
},
|
|
// 每页条数
|
|
pageSize: {
|
|
type: Number,
|
|
default: 10
|
|
},
|
|
// 是否正在加载
|
|
isLoading: {
|
|
type: Boolean,
|
|
default: false
|
|
}
|
|
},
|
|
data() {
|
|
return {
|
|
jumpPage: this.currentPage,
|
|
endPage: false
|
|
}
|
|
},
|
|
computed: {
|
|
// 总页数
|
|
totalPages() {
|
|
return Math.ceil(this.totalRecords / this.pageSize)
|
|
},
|
|
// 是否显示首页按钮
|
|
showFirstPage() {
|
|
return this.currentPage > 2;
|
|
},
|
|
// 是否显示上一页按钮
|
|
showPrevPage() {
|
|
return this.currentPage > 1 || this.endPage
|
|
},
|
|
// 是否显示当前页码
|
|
showCurrentPage() {
|
|
return true
|
|
},
|
|
// 是否显示下一页按钮
|
|
showNextPage() {
|
|
return this.hasNextPage && !this.endPage
|
|
},
|
|
// 是否显示尾页按钮
|
|
showLastPage() {
|
|
return !this.endPage
|
|
},
|
|
// 是否显示跳转
|
|
showJump() {
|
|
return true
|
|
},
|
|
// 是否显示总记录数
|
|
showTotalRecords() {
|
|
return Number(this.totalRecords) > 0
|
|
}
|
|
},
|
|
watch: {
|
|
currentPage(newVal) {
|
|
this.jumpPage = newVal
|
|
}
|
|
},
|
|
methods: {
|
|
// 跳转到首页
|
|
goToFirstPage() {
|
|
if (this.currentPage === 1 || this.isLoading) return
|
|
this.endPage = false
|
|
this.$emit('page-change', {
|
|
page: 1,
|
|
endPage: false,
|
|
direction: 'first'
|
|
})
|
|
},
|
|
|
|
// 跳转到上一页
|
|
goToPrevPage() {
|
|
if (this.currentPage <= 1 || this.isLoading) return
|
|
this.endPage = false
|
|
this.$emit('page-change', {
|
|
page: this.currentPage - 1,
|
|
endPage: false,
|
|
direction: 'prev'
|
|
})
|
|
},
|
|
|
|
// 跳转到下一页
|
|
goToNextPage() {
|
|
if (!this.hasNextPage || this.isLoading) return
|
|
this.endPage = false
|
|
this.$emit('page-change', {
|
|
page: this.currentPage + 1,
|
|
endPage: false,
|
|
direction: 'next'
|
|
})
|
|
},
|
|
|
|
// 跳转到尾页
|
|
goToLastPage() {
|
|
if (this.endPage || this.isLoading) return
|
|
this.endPage = true
|
|
this.$emit('page-change', {
|
|
page: this.totalPages,
|
|
endPage: true,
|
|
direction: 'last'
|
|
})
|
|
},
|
|
|
|
// 处理跳转
|
|
handleJump() {
|
|
let page = parseInt(this.jumpPage)
|
|
if (isNaN(page)) page = 1
|
|
|
|
// 限制最大页数
|
|
if (page > this.totalPages) {
|
|
page = this.totalPages
|
|
this.jumpPage = page
|
|
}
|
|
|
|
if (page === this.currentPage || this.isLoading) return
|
|
|
|
this.endPage = false
|
|
this.$emit('page-change', {
|
|
page,
|
|
endPage: false,
|
|
direction: 'jump'
|
|
})
|
|
}
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<style scoped>
|
|
.pagination {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: flex-end;
|
|
margin: 20px 0;
|
|
gap: 10px;
|
|
}
|
|
|
|
.page-jump input {
|
|
width: 50px;
|
|
padding: 5px;
|
|
border: 1px solid #ddd;
|
|
border-radius: 3px;
|
|
text-align: center;
|
|
}
|
|
|
|
.total-records {
|
|
margin-left: 10px;
|
|
color: #666;
|
|
}
|
|
</style>
|