vue分页实现原理
Vue 分页实现原理
Vue 分页的核心原理是通过计算当前页的数据范围,动态渲染数据列表并控制分页组件的交互。以下是关键实现步骤:
数据分片计算
分页需要根据当前页码和每页条数截取数据。假设原始数据为 totalData,计算公式如下:

- 起始索引:
(currentPage - 1) * pageSize - 结束索引:
currentPage * pageSize - 当前页数据:
totalData.slice(startIndex, endIndex)
computed: {
paginatedData() {
const start = (this.currentPage - 1) * this.pageSize;
const end = start + this.pageSize;
return this.totalData.slice(start, end);
}
}
分页组件交互
分页组件通常包含页码按钮、上一页/下一页按钮,逻辑如下:

- 总页数计算:
Math.ceil(totalData.length / pageSize) - 页码切换:更新
currentPage触发数据重新分片 - 禁用逻辑:第一页时禁用“上一页”,最后一页时禁用“下一页”
methods: {
goToPage(page) {
if (page >= 1 && page <= this.totalPages) {
this.currentPage = page;
}
}
}
动态页码渲染
根据当前页和总页数生成页码列表,常见策略:
- 固定显示前后几页(如1, 2, ..., 5, 6, 7, ..., 10)
- 使用
v-for循环渲染可点击的页码按钮
computed: {
displayedPages() {
const range = 2; // 前后显示范围
const start = Math.max(1, this.currentPage - range);
const end = Math.min(this.totalPages, this.currentPage + range);
return Array.from({ length: end - start + 1 }, (_, i) => start + i);
}
}
与后端交互(可选)
对于大数据量场景,通常通过 API 分页:
- 传递参数:
page(页码)、pageSize(每页条数) - 后端返回:当前页数据
data和总数total
async fetchData() {
const res = await api.get('/list', {
params: { page: this.currentPage, pageSize: this.pageSize }
});
this.paginatedData = res.data;
this.total = res.total;
}
完整示例代码
<template>
<div>
<ul>
<li v-for="item in paginatedData" :key="item.id">{{ item.name }}</li>
</ul>
<div class="pagination">
<button @click="goToPage(currentPage - 1)" :disabled="currentPage === 1">上一页</button>
<button
v-for="page in displayedPages"
:key="page"
@click="goToPage(page)"
:class="{ active: page === currentPage }"
>
{{ page }}
</button>
<button @click="goToPage(currentPage + 1)" :disabled="currentPage === totalPages">下一页</button>
</div>
</div>
</template>
<script>
export default {
data() {
return {
totalData: [], // 原始数据
currentPage: 1,
pageSize: 10,
total: 0
};
},
computed: {
paginatedData() {
const start = (this.currentPage - 1) * this.pageSize;
const end = start + this.pageSize;
return this.totalData.slice(start, end);
},
totalPages() {
return Math.ceil(this.totalData.length / this.pageSize);
},
displayedPages() {
const range = 2;
const start = Math.max(1, this.currentPage - range);
const end = Math.min(this.totalPages, this.currentPage + range);
return Array.from({ length: end - start + 1 }, (_, i) => start + i);
}
},
methods: {
goToPage(page) {
if (page >= 1 && page <= this.totalPages) {
this.currentPage = page;
}
}
}
};
</script>
优化方向
- 性能:大数据量时使用虚拟滚动(如
vue-virtual-scroller) - UI 扩展:添加跳转输入框、每页条数选择器
- 路由集成:将页码同步到 URL 的 query 参数(如
?page=2)






