vue 分页如何实现
分页实现的基本思路
在Vue中实现分页功能通常需要结合后端API返回的分页数据(如当前页码、每页条数、总条数等)和前端UI组件。核心逻辑包括处理页码切换、数据请求和列表渲染。
后端API数据格式
典型的分页接口响应格式如下:
{
"data": [...], // 当前页数据列表
"current_page": 1, // 当前页码
"per_page": 10, // 每页条数
"total": 100 // 总条数
}
前端实现步骤
定义分页状态
data() {
return {
list: [], // 数据列表
pagination: {
currentPage: 1, // 当前页
pageSize: 10, // 每页条数
total: 0 // 总条数
}
}
}
请求分页数据方法
methods: {
async fetchData() {
const { currentPage, pageSize } = this.pagination
const res = await api.getList({
page: currentPage,
size: pageSize
})
this.list = res.data
this.pagination.total = res.total
}
}
Element UI分页组件示例
<el-pagination
:current-page="pagination.currentPage"
:page-size="pagination.pageSize"
:total="pagination.total"
@current-change="handlePageChange"
layout="total, prev, pager, next">
</el-pagination>
处理页码变更
methods: {
handlePageChange(page) {
this.pagination.currentPage = page
this.fetchData()
}
}
自定义分页组件实现
如果需要自定义分页UI,可以这样实现:
模板部分
<div class="pagination">
<button
@click="prevPage"
:disabled="currentPage === 1">
上一页
</button>
<span v-for="page in pageRange"
@click="goToPage(page)"
:class="{ active: page === currentPage }">
{{ page }}
</span>
<button
@click="nextPage"
:disabled="currentPage === totalPages">
下一页
</button>
</div>
逻辑部分
computed: {
totalPages() {
return Math.ceil(this.total / this.pageSize)
},
pageRange() {
// 生成可见页码范围逻辑
const range = []
for (let i = 1; i <= this.totalPages; i++) {
range.push(i)
}
return range
}
},
methods: {
goToPage(page) {
this.currentPage = page
this.$emit('page-change', page)
}
}
性能优化建议
- 添加加载状态避免重复请求
data() { return { loading: false } }
methods: { async fetchData() { if (this.loading) return this.loading = true try { // ...请求逻辑 } finally { this.loading = false } } }

- 使用防抖处理快速翻页
```javascript
import { debounce } from 'lodash'
methods: {
handlePageChange: debounce(function(page) {
this.pagination.currentPage = page
this.fetchData()
}, 300)
}
完整示例代码
<template>
<div>
<ul>
<li v-for="item in list" :key="item.id">{{ item.name }}</li>
</ul>
<el-pagination
v-model:current-page="pagination.currentPage"
:page-size="pagination.pageSize"
:total="pagination.total"
@current-change="fetchData"
layout="prev, pager, next">
</el-pagination>
</div>
</template>
<script>
export default {
data() {
return {
list: [],
pagination: {
currentPage: 1,
pageSize: 10,
total: 0
}
}
},
mounted() {
this.fetchData()
},
methods: {
async fetchData() {
const res = await api.getList({
page: this.pagination.currentPage,
size: this.pagination.pageSize
})
this.list = res.data
this.pagination.total = res.total
}
}
}
</script>






