How To Build a Reusable Pagination Component (ok)
https://codepen.io/alligatorio/pen/zWvpRp
Last updated
https://codepen.io/alligatorio/pen/zWvpRp
Last updated
$npx @vue/cli create --default vue-pagination-example
$cd vue-pagination-example
C:\xampp\htdocs\vue-pagination-example\src\components\Pagination-test.vue
<template>
<ul class="pagination">
<li class="pagination-item">
<button
type="button"
@click="onClickFirstPage"
:disabled="isInFirstPage"
>
First
</button>
</li>
<li class="pagination-item">
<button
type="button"
@click="onClickPreviousPage"
:disabled="isInFirstPage"
>
Previous
</button>
</li>
<!-- Visible Buttons Start -->
<li
v-for="page in pages"
:key="page.name"
class="pagination-item"
>
<button
type="button"
@click="onClickPage(page.name)"
:disabled="page.isDisabled"
:class="{ active: isPageActive(page.name) }"
>
{{ page.name }}
</button>
</li>
<!-- Visible Buttons End -->
<li class="pagination-item">
<button
type="button"
@click="onClickNextPage"
:disabled="isInLastPage"
>
Next
</button>
</li>
<li class="pagination-item">
<button
type="button"
@click="onClickLastPage"
:disabled="isInLastPage"
>
Last
</button>
</li>
</ul>
</template>
<script>
export default {
props: {
maxVisibleButtons: {
type: Number,
required: false,
default: 3
},
totalPages: {
type: Number,
required: true
},
perPage: {
type: Number,
required: true
},
currentPage: {
type: Number,
required: true
}
},
computed: {
startPage() {
// When on the first page
if (this.currentPage === 1) {
return 1;
}
// When on the last page
if (this.currentPage === this.totalPages) {
return this.totalPages - this.maxVisibleButtons;
}
// When inbetween
return this.currentPage - 1;
},
pages() {
const range = [];
for (
let i = this.startPage;
i <= Math.min(this.startPage + this.maxVisibleButtons - 1, this.totalPages);
i++
) {
range.push({
name: i,
isDisabled: i === this.currentPage
});
}
return range;
},
isInFirstPage() {
return this.currentPage === 1;
},
isInLastPage() {
return this.currentPage === this.totalPages;
},
},
methods: {
onClickFirstPage() {
this.$emit('pagechanged', 1);
},
isPageActive(page) {
return this.currentPage === page;
},
onClickPreviousPage() {
this.$emit('pagechanged', this.currentPage - 1);
},
onClickPage(page) {
this.$emit('pagechanged', page);
},
onClickNextPage() {
this.$emit('pagechanged', this.currentPage + 1);
},
onClickLastPage() {
this.$emit('pagechanged', this.totalPages);
}
}
};
</script>
<style>
.pagination {
list-style-type: none;
}
.pagination-item {
display: inline-block;
}
.active {
background-color: #4AAE9B;
color: #ffffff;
}
</style>
C:\xampp\htdocs\vue-pagination-example\src\App.vue
<template>
<div id="app">
<pagination
:totalPages="10"
:perPage="10"
:currentPage="currentPage"
@pagechanged="onPageChange"
/>
</div>
</template>
<script>
import Pagination from './components/Pagination-test.vue'
export default {
name: 'App',
components: {
Pagination
},
data () {
return {
currentPage: 1,
};
},
methods: {
onPageChange(page) {
console.log(page)
this.currentPage = page;
}
}
}
</script>