
2 changed files with 238 additions and 176 deletions
@ -1,238 +1,279 @@ |
|||||
<template> |
<template> |
||||
<div class="pagination"> |
<div class="pagination flex gap10"> |
||||
<!-- 首页按钮 --> |
<!-- 首页按钮 --> |
||||
<button |
<GuipButton size="form" v-if="showFirstPage" @click="goToFirstPage" :disabled="page === 1"> |
||||
v-if="showHome" |
|
||||
@click="goToFirstPage" |
|
||||
class="pagination-button" |
|
||||
> |
|
||||
首页 |
首页 |
||||
</button> |
</GuipButton> |
||||
|
|
||||
<!-- 上一页按钮 --> |
<!-- 上一页按钮 --> |
||||
<button |
<GuipButton size="form" v-if="showPrevPage" @click="goToPrevPage" :disabled="page === 1"> |
||||
v-if="showPrev" |
|
||||
@click="goToPrevPage" |
|
||||
class="pagination-button" |
|
||||
> |
|
||||
上一页 |
上一页 |
||||
</button> |
</GuipButton> |
||||
|
|
||||
<!-- 当前页码显示 --> |
<!-- 当前页码 --> |
||||
<span v-if="showCurrent" class="current-page">第{{ currentPage }}页</span> |
<span v-if="showCurrentPage">第{{ page }}页</span> |
||||
|
|
||||
<!-- 下一页按钮 --> |
<!-- 下一页按钮 --> |
||||
<button |
<GuipButton size="form" v-if="showNextPage" @click="goToNextPage" :disabled="!hasNextPage "> |
||||
v-if="showNext" |
|
||||
@click="goToNextPage" |
|
||||
class="pagination-button" |
|
||||
> |
|
||||
下一页 |
下一页 |
||||
</button> |
</GuipButton> |
||||
|
|
||||
<!-- 尾页按钮/状态 --> |
<!-- 尾页按钮 --> |
||||
<button |
<GuipButton size="form" v-if="showLastPage" @click="goToLastPage"> |
||||
v-if="showLastButton" |
|
||||
@click="goToLastPage" |
|
||||
class="pagination-button" |
|
||||
> |
|
||||
尾页 |
尾页 |
||||
</button> |
</GuipButton> |
||||
<span v-if="showLastText" class="last-page">尾页</span> |
|
||||
|
<!-- 跳转输入 --> |
||||
<!-- 尾页时的页码显示 --> |
<div class="page-jump flex gap10" v-if="showJump"> |
||||
<span v-if="endPageFlag" class="last-page-number">第{{ totalPages }}页</span> |
<input type="number" v-model.number="jumpPage" min="1" :max="totalPages"> |
||||
|
<GuipButton size="form" @click="handleJump">跳转</GuipButton> |
||||
<!-- 跳转控件 --> |
|
||||
<div class="page-jump"> |
|
||||
<input |
|
||||
type="number" |
|
||||
v-model="jumpPage" |
|
||||
min="1" |
|
||||
class="jump-input" |
|
||||
> |
|
||||
<button @click="handleJump" class="jump-button">跳转</button> |
|
||||
</div> |
</div> |
||||
|
|
||||
<!-- 尾页时的总记录数 --> |
<!-- 总记录数 --> |
||||
<span v-if="endPageFlag" class="total-records">共{{ totalRecords }}条记录</span> |
<span v-if="showTotalRecords" class="total-records">共{{ totalRecords }}条记录</span> |
||||
</div> |
</div> |
||||
</template> |
</template> |
||||
|
|
||||
<script> |
<script> |
||||
|
import GuipButton from '@/components/GuipButton.vue'; |
||||
|
|
||||
export default { |
export default { |
||||
name: 'Pagination', |
name: 'Pagination', |
||||
|
components:{GuipButton}, |
||||
props: { |
props: { |
||||
// 总记录数 |
// 接口URL |
||||
totalRecords: { |
apiUrl: { |
||||
type: [Number,String], |
type: String, |
||||
required: true, |
required: true |
||||
default: 0 |
}, |
||||
}, |
// 每页条数 |
||||
// 总页数 |
pageSize: { |
||||
totalPages: { |
type: Number, |
||||
type: [Number,String], |
default: 10 |
||||
required: true, |
}, |
||||
default: 1 |
// 其他请求参数 |
||||
}, |
extraParams: { |
||||
// 当前页码 |
type: Object, |
||||
currentPage: { |
default: () => ({}) |
||||
type: [Number,String], |
|
||||
required: true, |
|
||||
default: 1 |
|
||||
}, |
|
||||
// 用于下一页的minid |
|
||||
nextMinId: { |
|
||||
type: [Number,String], |
|
||||
default: null |
|
||||
}, |
|
||||
// 用于上一页的maxid |
|
||||
prevMaxId: { |
|
||||
type: [Number,String], |
|
||||
default: null |
|
||||
} |
} |
||||
}, |
}, |
||||
data() { |
data() { |
||||
return { |
return { |
||||
endPageFlag: false, // 尾页标识 |
page: 1, |
||||
jumpPage: null // 跳转页码 |
jumpPage: 1, |
||||
}; |
end_page:0, |
||||
|
hasNextPage: false, |
||||
|
minId: null, |
||||
|
maxId: null, |
||||
|
totalRecords: 0, |
||||
|
buttonType:'', |
||||
|
totalPages: 1, |
||||
|
isLoading: false, |
||||
|
token: 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpYXQiOjE3NTAwNTM3MjQsIm5iZiI6MTc1MDA1MzcyNCwiZXhwIjoxNzUyNjQ1NzI0LCJ1c2VyIjoic3VidXNlciIsImxvZ2luX3R5cGUiOjAsImFpZCI6IjEifQ.xyIqBLelB-k6jCifgRevBJTyg_Qrm6m1e4OcHhOpepU', |
||||
|
} |
||||
}, |
}, |
||||
computed: { |
computed: { |
||||
// 是否显示首页按钮 |
// 是否显示首页按钮 |
||||
showHome() { |
showFirstPage() { |
||||
return this.currentPage > 1; |
return this.page > 2 |
||||
}, |
}, |
||||
// 是否显示上一页按钮 |
// 是否显示上一页按钮 |
||||
showPrev() { |
showPrevPage() { |
||||
return this.currentPage > 1; |
return this.page > 1 |
||||
}, |
}, |
||||
// 是否显示当前页码 |
// 是否显示当前页码 |
||||
showCurrent() { |
showCurrentPage() { |
||||
return !this.endPageFlag; |
return true |
||||
}, |
}, |
||||
// 是否显示下一页按钮 |
// 是否显示下一页按钮 |
||||
showNext() { |
showNextPage() { |
||||
return !this.endPageFlag; |
return this.hasNextPage |
||||
}, |
}, |
||||
// 是否显示尾页按钮 |
// 是否显示尾页按钮 |
||||
showLastButton() { |
showLastPage() { |
||||
return !this.endPageFlag; |
return !(this.end_page > 0) || this.hasNextPage |
||||
|
}, |
||||
|
// 是否显示跳转 |
||||
|
showJump() { |
||||
|
return true |
||||
}, |
}, |
||||
// 是否显示尾页文本 |
// 是否显示总记录数 |
||||
showLastText() { |
showTotalRecords() { |
||||
return this.endPageFlag; |
return this.totalRecords > 0 |
||||
} |
} |
||||
}, |
}, |
||||
|
created() { |
||||
|
this.fetchData() |
||||
|
}, |
||||
methods: { |
methods: { |
||||
|
// 构建请求参数 |
||||
|
buildParams() { |
||||
|
const params = { |
||||
|
pagesize: this.pageSize, |
||||
|
page:this.page, |
||||
|
...this.extraParams |
||||
|
} |
||||
|
|
||||
|
// 如果不是第一页,添加maxid或minid |
||||
|
if (this.page > 1) { |
||||
|
if (this.page === this.totalPages) { |
||||
|
// 从尾页往前翻 |
||||
|
params.maxid = this.maxId |
||||
|
} else { |
||||
|
// 正常翻页 |
||||
|
if (this.buttonType == 'prev') { |
||||
|
params.maxid = this.maxId |
||||
|
} else { |
||||
|
params.minid = this.minId |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
if(this.end_page > 0){ |
||||
|
delete params.page |
||||
|
delete params.maxid |
||||
|
delete params.minid |
||||
|
params.end_page = this.end_page |
||||
|
}else{ |
||||
|
delete params.end_page |
||||
|
} |
||||
|
|
||||
|
console.log(params,'params======'); |
||||
|
return params |
||||
|
}, |
||||
|
|
||||
|
// 获取数据 |
||||
|
async fetchData() { |
||||
|
console.log('-----执行了'); |
||||
|
this.isLoading = true |
||||
|
this.$emit('changeLoad',true) |
||||
|
try { |
||||
|
this.$http('POST', this.apiUrl, this.buildParams(), { |
||||
|
headers: { |
||||
|
'Auth': this.token |
||||
|
} |
||||
|
}).then(response => { |
||||
|
const data = response.data |
||||
|
this.hasNextPage = data.is_has_next_page |
||||
|
this.minId = data.minid || null |
||||
|
this.maxId = data.maxid || null |
||||
|
this.totalRecords = data.total_records || 0 |
||||
|
if(this.totalRecords > 0){ |
||||
|
// 计算总页数 |
||||
|
this.totalPages = Math.ceil(this.totalRecords / this.pageSize) |
||||
|
this.page = this.totalPages || 1 |
||||
|
this.jumpPage = this.page |
||||
|
} |
||||
|
// 通知父组件数据更新 |
||||
|
this.$emit('update', data) |
||||
|
this.$emit('changeLoad',false) |
||||
|
}) |
||||
|
} catch (error) { |
||||
|
console.error('分页请求失败:', error) |
||||
|
this.$emit('error', error) |
||||
|
this.$emit('changeLoad',false) |
||||
|
} finally { |
||||
|
this.isLoading = false |
||||
|
this.$emit('changeLoad',false) |
||||
|
} |
||||
|
}, |
||||
|
|
||||
// 跳转到首页 |
// 跳转到首页 |
||||
goToFirstPage() { |
goToFirstPage() { |
||||
this.endPageFlag = false; |
if (this.page === 1) return |
||||
this.$emit('page-change', { |
this.page = 1 |
||||
page: 1, |
this.jumpPage = 1 |
||||
isFirst: true |
this.end_page = 0; |
||||
}); |
this.buttonType = '' |
||||
|
this.fetchData() |
||||
}, |
}, |
||||
|
|
||||
// 跳转到上一页 |
// 跳转到上一页 |
||||
goToPrevPage() { |
goToPrevPage() { |
||||
this.endPageFlag = false; |
if (this.page <= 1) return |
||||
this.$emit('page-change', { |
this.page-- |
||||
page: this.currentPage - 1, |
this.jumpPage = this.page |
||||
maxid: this.prevMaxId, |
this.end_page = 0; |
||||
isPrev: true |
this.buttonType = 'prev' |
||||
}); |
this.fetchData() |
||||
}, |
}, |
||||
|
|
||||
// 跳转到下一页 |
// 跳转到下一页 |
||||
goToNextPage() { |
goToNextPage() { |
||||
this.endPageFlag = false; |
if (!this.hasNextPage)return |
||||
this.$emit('page-change', { |
this.page++ |
||||
page: this.currentPage + 1, |
this.end_page = 0; |
||||
minid: this.nextMinId, |
this.jumpPage = this.page |
||||
isNext: true |
this.buttonType = 'next' |
||||
}); |
this.fetchData() |
||||
}, |
}, |
||||
|
|
||||
// 跳转到尾页 |
// 跳转到尾页 |
||||
goToLastPage() { |
goToLastPage() { |
||||
this.endPageFlag = true; |
// if (this.page === this.totalPages) return |
||||
this.$emit('page-change', { |
// this.page = this.totalPages |
||||
page: this.totalPages, |
// this.jumpPage = this.totalPages |
||||
isLast: true |
this.end_page = 1; |
||||
}); |
this.buttonType = '' |
||||
|
this.fetchData() |
||||
}, |
}, |
||||
|
|
||||
// 处理跳转 |
// 处理跳转 |
||||
handleJump() { |
handleJump() { |
||||
if (!this.jumpPage || this.jumpPage < 1) { |
let page = parseInt(this.jumpPage) |
||||
return; |
|
||||
|
if (isNaN(page) || page < 1) { |
||||
|
page = 1 |
||||
} |
} |
||||
if (this.totalPages > 0 && this.jumpPage > this.totalPages) { |
// else if (page > this.totalPages) { |
||||
return; |
// page = this.totalPages |
||||
|
// } |
||||
|
|
||||
|
if (page === this.page) return |
||||
|
|
||||
|
this.page = page |
||||
|
this.jumpPage = page |
||||
|
this.fetchData() |
||||
|
} |
||||
|
}, |
||||
|
watch: { |
||||
|
apiUrl() { |
||||
|
this.page = 1 |
||||
|
this.fetchData() |
||||
|
}, |
||||
|
pageSize() { |
||||
|
this.page = 1 |
||||
|
this.fetchData() |
||||
|
}, |
||||
|
extraParams: { |
||||
|
deep: true, |
||||
|
handler() { |
||||
|
this.page = 1 |
||||
|
this.fetchData() |
||||
} |
} |
||||
|
|
||||
this.endPageFlag = this.jumpPage === this.totalPages; |
|
||||
|
|
||||
this.$emit('page-change', { |
|
||||
page: this.jumpPage, |
|
||||
isJump: true |
|
||||
}); |
|
||||
|
|
||||
this.jumpPage = null; |
|
||||
} |
} |
||||
} |
} |
||||
}; |
} |
||||
</script> |
</script> |
||||
|
|
||||
<style scoped> |
<style scoped> |
||||
.pagination { |
.pagination { |
||||
display: flex; |
display: flex; |
||||
align-items: center; |
align-items: center; |
||||
gap: 8px; |
justify-content: flex-end; |
||||
margin-top: 20px; |
margin: 20px 0; |
||||
flex-wrap: wrap; |
gap: 10px; |
||||
} |
|
||||
|
|
||||
.pagination-button { |
|
||||
padding: 6px 12px; |
|
||||
border: 1px solid #ddd; |
|
||||
background: #f8f8f8; |
|
||||
border-radius: 4px; |
|
||||
cursor: pointer; |
|
||||
} |
|
||||
|
|
||||
.pagination-button:hover { |
|
||||
background: #e8e8e8; |
|
||||
} |
|
||||
|
|
||||
.current-page, .last-page, .last-page-number, .total-records { |
|
||||
padding: 0 8px; |
|
||||
font-size: 14px; |
|
||||
} |
} |
||||
|
|
||||
.page-jump { |
.page-jump input { |
||||
display: flex; |
|
||||
gap: 4px; |
|
||||
} |
|
||||
|
|
||||
.jump-input { |
|
||||
width: 50px; |
width: 50px; |
||||
padding: 4px; |
padding: 5px; |
||||
border: 1px solid #ddd; |
border: 1px solid #ddd; |
||||
border-radius: 4px; |
border-radius: 3px; |
||||
text-align: center; |
text-align: center; |
||||
} |
} |
||||
|
|
||||
.jump-button { |
.total-records { |
||||
padding: 4px 8px; |
margin-left: 10px; |
||||
border: 1px solid #ddd; |
color: #666; |
||||
background: #f0f0f0; |
|
||||
border-radius: 4px; |
|
||||
cursor: pointer; |
|
||||
} |
|
||||
|
|
||||
.jump-button:hover { |
|
||||
background: #e0e0e0; |
|
||||
} |
} |
||||
</style> |
</style> |
Loading…
Reference in new issue