vue实现分页功能例子
以下是一个基于 Vue 3 的分页功能实现示例,包含基本逻辑和样式:

基础实现代码
<template>
<div class="pagination-container">
<button
@click="prevPage"
:disabled="currentPage === 1"
>上一页</button>
<span
v-for="page in visiblePages"
:key="page"
@click="goToPage(page)"
:class="{ active: page === currentPage }"
>{{ page }}</span>
<button
@click="nextPage"
:disabled="currentPage === totalPages"
>下一页</button>
</div>
</template>
<script setup>
import { ref, computed } from 'vue';
const props = defineProps({
totalItems: {
type: Number,
required: true
},
itemsPerPage: {
type: Number,
default: 10
}
});
const currentPage = ref(1);
const totalPages = computed(() =>
Math.ceil(props.totalItems / props.itemsPerPage)
);
const visiblePages = computed(() => {
const pages = [];
const maxVisible = 5;
let start = Math.max(1, currentPage.value - Math.floor(maxVisible / 2));
let end = Math.min(totalPages.value, start + maxVisible - 1);
if (end - start + 1 < maxVisible) {
start = Math.max(1, end - maxVisible + 1);
}
for (let i = start; i <= end; i++) {
pages.push(i);
}
return pages;
});
function prevPage() {
if (currentPage.value > 1) {
currentPage.value--;
}
}
function nextPage() {
if (currentPage.value < totalPages.value) {
currentPage.value++;
}
}
function goToPage(page) {
currentPage.value = page;
}
</script>
<style scoped>
.pagination-container {
display: flex;
gap: 8px;
align-items: center;
}
button {
padding: 4px 8px;
cursor: pointer;
}
button:disabled {
opacity: 0.5;
cursor: not-allowed;
}
span {
padding: 4px 8px;
cursor: pointer;
}
span.active {
font-weight: bold;
color: #42b983;
}
</style>
使用示例
<template>
<div>
<!-- 显示分页数据 -->
<ul>
<li v-for="item in paginatedData" :key="item.id">
{{ item.name }}
</li>
</ul>
<!-- 分页组件 -->
<Pagination
:total-items="data.length"
:items-per-page="itemsPerPage"
@page-change="handlePageChange"
/>
</div>
</template>
<script setup>
import { ref, computed } from 'vue';
import Pagination from './Pagination.vue';
const data = ref([
{ id: 1, name: 'Item 1' },
// ...更多数据
]);
const itemsPerPage = 5;
const currentPage = ref(1);
const paginatedData = computed(() => {
const start = (currentPage.value - 1) * itemsPerPage;
const end = start + itemsPerPage;
return data.value.slice(start, end);
});
function handlePageChange(page) {
currentPage.value = page;
}
</script>
高级功能扩展
-
添加每页条数选择器:

<select v-model="itemsPerPage" @change="resetPage"> <option value="5">5条/页</option> <option value="10">10条/页</option> <option value="20">20条/页</option> </select> -
添加跳转输入框:
<input type="number" v-model="inputPage" min="1" :max="totalPages" @keyup.enter="goToInputPage" > -
添加省略号显示:
const visiblePages = computed(() => { // ...原有逻辑 if (start > 1) pages.unshift('...'); if (end < totalPages.value) pages.push('...'); return pages; });
注意事项
- 分页组件应通过
v-model或事件与父组件通信 - 大数据量时考虑使用虚拟滚动代替传统分页
- 移动端需调整样式为更适合触摸操作的布局
- 可结合Vue Router实现URL同步分页状态






