vue 分页功能实现
Vue 分页功能实现
分页组件基础结构
创建一个独立的 Pagination.vue 组件,包含页码按钮、上一页/下一页按钮和页码范围显示。核心模板结构如下:
<template>
<div class="pagination">
<button @click="prevPage" :disabled="currentPage === 1">上一页</button>
<span v-for="page in pages" :key="page">
<button
@click="changePage(page)"
:class="{ active: currentPage === page }"
>{{ page }}</button>
</span>
<button @click="nextPage" :disabled="currentPage === totalPages">下一页</button>
</div>
</template>
计算属性处理页码逻辑
通过计算属性动态生成页码范围,避免显示过多页码按钮:
computed: {
pages() {
const range = [];
const start = Math.max(1, this.currentPage - 2);
const end = Math.min(this.totalPages, this.currentPage + 2);
for (let i = start; i <= end; i++) {
range.push(i);
}
return range;
}
}
父组件数据交互
父组件通过 props 传递总数据量和当前页码,通过事件触发页码变化:
props: {
totalItems: {
type: Number,
required: true
},
itemsPerPage: {
type: Number,
default: 10
},
currentPage: {
type: Number,
required: true
}
},
methods: {
changePage(page) {
this.$emit('page-changed', page);
}
}
数据分页处理
在父组件中使用分页组件,并实现数据切片逻辑:
data() {
return {
allData: [], // 全部数据
currentPage: 1,
perPage: 10
};
},
computed: {
paginatedData() {
const start = (this.currentPage - 1) * this.perPage;
const end = start + this.perPage;
return this.allData.slice(start, end);
}
}
样式优化
添加基础样式增强分页组件视觉效果:
.pagination button {
margin: 0 5px;
padding: 5px 10px;
border: 1px solid #ddd;
}
.pagination button.active {
background-color: #42b983;
color: white;
}
.pagination button:disabled {
opacity: 0.5;
cursor: not-allowed;
}
完整组件示例
整合后的分页组件完整代码:
<template>
<div class="pagination">
<button @click="prevPage" :disabled="currentPage === 1">上一页</button>
<span v-for="page in pages" :key="page">
<button
@click="changePage(page)"
:class="{ active: currentPage === page }"
>{{ page }}</button>
</span>
<button @click="nextPage" :disabled="currentPage === totalPages">下一页</button>
</div>
</template>
<script>
export default {
props: {
totalItems: Number,
itemsPerPage: {
type: Number,
default: 10
},
currentPage: {
type: Number,
required: true
}
},
computed: {
totalPages() {
return Math.ceil(this.totalItems / this.itemsPerPage);
},
pages() {
const range = [];
const start = Math.max(1, this.currentPage - 2);
const end = Math.min(this.totalPages, this.currentPage + 2);
for (let i = start; i <= end; i++) {
range.push(i);
}
return range;
}
},
methods: {
changePage(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>





