vue实现分页组件
实现分页组件的基本思路
Vue中实现分页组件通常需要处理数据分页逻辑、页码渲染以及用户交互。核心是通过计算属性动态生成页码列表,并通过事件向父组件传递当前页码变化。
基础分页组件代码示例
<template>
<div class="pagination">
<button
@click="changePage(currentPage - 1)"
:disabled="currentPage === 1"
>上一页</button>
<span
v-for="page in displayedPages"
:key="page"
@click="changePage(page)"
:class="{ active: page === currentPage }"
>{{ page }}</span>
<button
@click="changePage(currentPage + 1)"
:disabled="currentPage === totalPages"
>下一页</button>
</div>
</template>
<script>
export default {
props: {
totalItems: Number,
itemsPerPage: Number,
currentPage: Number,
maxVisiblePages: {
type: Number,
default: 5
}
},
computed: {
totalPages() {
return Math.ceil(this.totalItems / this.itemsPerPage)
},
displayedPages() {
const range = []
const half = Math.floor(this.maxVisiblePages / 2)
let start = Math.max(this.currentPage - half, 1)
let end = Math.min(start + this.maxVisiblePages - 1, this.totalPages)
if (end - start + 1 < this.maxVisiblePages) {
start = Math.max(end - this.maxVisiblePages + 1, 1)
}
for (let i = start; i <= end; i++) {
range.push(i)
}
return range
}
},
methods: {
changePage(page) {
if (page >= 1 && page <= this.totalPages) {
this.$emit('page-changed', page)
}
}
}
}
</script>
<style>
.pagination {
display: flex;
gap: 5px;
}
.pagination button {
padding: 5px 10px;
}
.pagination span {
padding: 5px 10px;
cursor: pointer;
}
.pagination span.active {
background-color: #42b983;
color: white;
}
</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"
:current-page="currentPage"
@page-changed="handlePageChange"
/>
</div>
</template>
<script>
import Pagination from './Pagination.vue'
export default {
components: { Pagination },
data() {
return {
data: [], // 从API获取的数据
itemsPerPage: 10,
currentPage: 1
}
},
computed: {
paginatedData() {
const start = (this.currentPage - 1) * this.itemsPerPage
const end = start + this.itemsPerPage
return this.data.slice(start, end)
}
},
methods: {
handlePageChange(page) {
this.currentPage = page
// 可以在这里添加获取新页数据的逻辑
}
}
}
</script>
高级功能扩展
添加省略号指示更多页码 当页码较多时,可以在组件中添加省略号指示被隐藏的页码:

displayedPages() {
const range = []
const half = Math.floor(this.maxVisiblePages / 2)
let start = Math.max(this.currentPage - half, 1)
let end = Math.min(start + this.maxVisiblePages - 1, this.totalPages)
if (end - start + 1 < this.maxVisiblePages) {
start = Math.max(end - this.maxVisiblePages + 1, 1)
}
// 添加前导省略号
if (start > 1) {
range.push(1)
if (start > 2) {
range.push('...')
}
}
for (let i = start; i <= end; i++) {
range.push(i)
}
// 添加后导省略号
if (end < this.totalPages) {
if (end < this.totalPages - 1) {
range.push('...')
}
range.push(this.totalPages)
}
return range
}
添加每页显示数量选择器 在分页组件中添加一个下拉菜单,允许用户选择每页显示的项目数:
<select v-model="localItemsPerPage" @change="handleItemsPerPageChange">
<option value="5">5 条/页</option>
<option value="10">10 条/页</option>
<option value="20">20 条/页</option>
<option value="50">50 条/页</option>
</select>
data() {
return {
localItemsPerPage: this.itemsPerPage
}
},
methods: {
handleItemsPerPageChange() {
this.$emit('items-per-page-changed', parseInt(this.localItemsPerPage))
this.$emit('page-changed', 1) // 重置到第一页
}
}
性能优化建议
对于大数据量分页,建议使用后端分页而非前端分页。修改组件从API获取分页数据:

methods: {
handlePageChange(page) {
this.currentPage = page
this.fetchData()
},
fetchData() {
axios.get('/api/data', {
params: {
page: this.currentPage,
per_page: this.itemsPerPage
}
}).then(response => {
this.data = response.data.items
this.totalItems = response.data.total
})
}
}
样式自定义技巧
通过插槽允许自定义页码按钮样式:
<template #page-button="{ page, isActive }">
<button :class="{ active: isActive }">
{{ page }}
</button>
</template>
通过props传递CSS类名实现主题定制:
props: {
activeClass: {
type: String,
default: 'active'
},
disabledClass: {
type: String,
default: 'disabled'
}
}






