vue实现分页页码
实现分页页码的基本思路
在Vue中实现分页页码功能,通常需要结合后端API返回的数据和前端的分页逻辑。核心是通过计算属性动态生成页码数组,并处理页码切换事件。
基础实现方案
模板部分
<template>
<div class="pagination">
<button @click="prevPage" :disabled="currentPage === 1">上一页</button>
<span
v-for="page in displayedPages"
:key="page"
@click="changePage(page)"
:class="{ active: currentPage === page }"
>
{{ page }}
</span>
<button @click="nextPage" :disabled="currentPage === totalPages">下一页</button>
</div>
</template>
脚本部分
<script>
export default {
props: {
totalItems: Number,
itemsPerPage: Number,
maxDisplayedPages: {
type: Number,
default: 5
}
},
data() {
return {
currentPage: 1
}
},
computed: {
totalPages() {
return Math.ceil(this.totalItems / this.itemsPerPage)
},
displayedPages() {
const pages = []
const half = Math.floor(this.maxDisplayedPages / 2)
let start = Math.max(1, this.currentPage - half)
let end = Math.min(this.totalPages, start + this.maxDisplayedPages - 1)
if (end - start + 1 < this.maxDisplayedPages) {
start = Math.max(1, end - this.maxDisplayedPages + 1)
}
for (let i = start; i <= end; i++) {
pages.push(i)
}
return pages
}
},
methods: {
changePage(page) {
if (page !== this.currentPage) {
this.currentPage = page
this.$emit('page-changed', page)
}
},
prevPage() {
if (this.currentPage > 1) {
this.changePage(this.currentPage - 1)
}
},
nextPage() {
if (this.currentPage < this.totalPages) {
this.changePage(this.currentPage + 1)
}
}
}
}
</script>
样式优化建议
<style scoped>
.pagination {
display: flex;
justify-content: center;
align-items: center;
gap: 8px;
margin: 20px 0;
}
.pagination button {
padding: 5px 10px;
cursor: pointer;
}
.pagination button:disabled {
opacity: 0.5;
cursor: not-allowed;
}
.pagination span {
padding: 5px 10px;
cursor: pointer;
border-radius: 3px;
}
.pagination span:hover {
background-color: #eee;
}
.pagination .active {
background-color: #42b983;
color: white;
}
</style>
高级功能扩展
省略号处理 当页码较多时,可以添加省略号表示隐藏的页码:
computed: {
displayedPages() {
const pages = []
const maxVisible = this.maxDisplayedPages
const total = this.totalPages
if (total <= maxVisible) {
for (let i = 1; i <= total; i++) pages.push(i)
return pages
}
const left = Math.max(2, this.currentPage - 1)
const right = Math.min(total - 1, this.currentPage + 1)
pages.push(1)
if (left > 2) pages.push('...')
for (let i = left; i <= right; i++) pages.push(i)
if (right < total - 1) pages.push('...')
pages.push(total)
return pages
}
}
模板调整
<span
v-for="(page, index) in displayedPages"
:key="index"
@click="typeof page === 'number' && changePage(page)"
:class="{
active: currentPage === page,
ellipsis: page === '...'
}"
>
{{ page }}
</span>
与后端API集成
实际项目中通常需要从后端获取分页数据:
methods: {
async fetchData(page = 1) {
try {
const response = await axios.get('/api/data', {
params: {
page,
limit: this.itemsPerPage
}
})
this.data = response.data.items
this.totalItems = response.data.total
this.currentPage = page
} catch (error) {
console.error(error)
}
}
}
使用第三方库
对于复杂需求,可以考虑使用现成的分页组件库:
v-pagination(Vue 2)vue-awesome-paginate(Vue 3)
安装示例:
npm install vue-awesome-paginate
使用示例:
import VueAwesomePaginate from "vue-awesome-paginate";
import "vue-awesome-paginate/dist/style.css";
// Vue 3
app.use(VueAwesomePaginate);
// 模板中使用
<vue-awesome-paginate
:total-items="totalItems"
:items-per-page="itemsPerPage"
v-model="currentPage"
/>






