用vue3的composition API写一个分页组件
这是一个用Vue 3的Composition API编写的基本分页组件示例:
<template>
<div class="pagination">
<button :disabled="currentPage === 1" @click="currentPage--">Prev</button>
<div class="pages">
<button v-for="page in pages" :key="page" @click="currentPage = page" :class="{ active: page === currentPage }">{{ page }}</button>
</div>
<button :disabled="currentPage === totalPages" @click="currentPage++">Next</button>
</div>
</template>
<script>
import { ref, computed, watch } from 'vue';
export default {
props: {
totalItems: {
type: Number,
required: true
},
pageSize: {
type: Number,
default: 10
},
initialPage: {
type: Number,
default: 1
},
maxPages: {
type: Number,
default: 10
}
},
setup(props) {
const currentPage = ref(props.initialPage);
const totalPages = computed(() => Math.ceil(props.totalItems / props.pageSize));
const pages = computed(() => {
const startPage = Math.max(1, currentPage.value - Math.floor(props.maxPages / 2));
const endPage = Math.min(totalPages.value, startPage + props.maxPages - 1);
return Array.from({ length: endPage - startPage + 1 }, (_, i) => startPage + i);
});
watch(currentPage, (newPage, oldPage) => {
if (newPage !== oldPage) {
const isValidPage = newPage > 0 && newPage <= totalPages.value;
if (isValidPage) {
props.$emit('update:currentPage', newPage);
} else {
currentPage.value = oldPage;
}
}
});
return {
currentPage,
totalPages,
pages
}
}
}
</script>
<style>
.pagination {
display: flex;
justify-content: center;
align-items: center;
margin: 20px 0;
}
.pages {
display: flex;
justify-content: center;
align-items: center;
margin: 0 10px;
}
button {
border: none;
background-color: #f4f4f4;
color: #333;
padding: 8px 16px;
cursor: pointer;
}
button.active {
background-color: #333;
color: #fff;
}
button:disabled {
opacity: 0.5;
cursor: not-allowed;
}
</style>
使用示例:
<template>
<div>
<ul>
<li v-for="item in visibleItems" :key="item">{{ item }}</li>
</ul>
<pagination :total-items="totalItems" :page-size="pageSize" :initial-page="currentPage" :max-pages="maxPages" @update:current-page="currentPage = $event" />
</div>
</template>
<script>
import Pagination from './Pagination.vue';
export default {
components: {
Pagination
},
data() {
return {
currentPage: 1,
totalItems: 100,
pageSize: 10,
maxPages: 10
}
},
computed: {
visibleItems() {
const start = (this.currentPage - 1) * this.pageSize;
const end = start + this.pageSize;
return Array.from({ length: this.totalItems }, (_, i) => i + 1).slice(start, end);
}
}
}
</script>
原文地址: https://www.cveoy.top/t/topic/0xV 著作权归作者所有。请勿转载和采集!