Pagination component
A pagination component should allow the user to go to the first and last pages, move forward and backwards and change directly to a page in a close range.
Made with
Html
Css
Javascript
Html
<div id="app">
<pagination
:total-pages="11"
:total="113"
:per-page="10"
:current-page="currentPage"
@pagechanged="onPageChange"
/>
</div>
<script type="text/x-template" id="pagination">
<ul class="pagination">
<li
class="pagination-item"
>
<button
type="button"
@click="onClickFirstPage"
:disabled="isInFirstPage"
aria-label="Go to first page"
>
First
</button>
</li>
<li
class="pagination-item"
>
<button
type="button"
@click="onClickPreviousPage"
:disabled="isInFirstPage"
aria-label="Go to previous page"
>
Previous
</button>
</li>
<li v-for="page in pages" class="pagination-item">
<button
type="button"
@click="onClickPage(page.name)"
:disabled="page.isDisabled"
:class="{ active: isPageActive(page.name) }"
:aria-label="`Go to page number ${page.name}`"
>
{{ page.name }}
</button>
</li>
<li class="pagination-item">
<button
type="button"
@click="onClickNextPage"
:disabled="isInLastPage"
aria-label="Go to next page"
>
Next
</button>
</li>
<li class="pagination-item">
<button
type="button"
@click="onClickLastPage"
:disabled="isInLastPage"
aria-label="Go to last page"
>
Last
</button>
</li>
</ul>
</script>
Css
#app {
font-family: Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
.pagination {
list-style-type: none;
}
.pagination-item {
display: inline-block;
}
.active {
background-color: #4AAE9B;
color: #ffffff;
}
Javascript
const Pagination = {
name: 'pagination',
template: '#pagination',
props: {
maxVisibleButtons: {
type: Number,
required: false,
default: 3
},
totalPages: {
type: Number,
required: true
},
total: {
type: Number,
required: true
},
perPage: {
type: Number,
required: true
},
currentPage: {
type: Number,
required: true
},
},
computed: {
startPage() {
if (this.currentPage === 1) {
return 1;
}
if (this.currentPage === this.totalPages) {
return this.totalPages - this.maxVisibleButtons + 1;
}
return this.currentPage - 1;
},
endPage() {
return Math.min(this.startPage + this.maxVisibleButtons - 1, this.totalPages);
},
pages() {
const range = [];
for (let i = this.startPage; i <= this.endPage; i+= 1 ) {
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);
},
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);
},
isPageActive(page) {
return this.currentPage === page;
},
}
};
new Vue({
el: '#app',
name: 'app',
components: {
pagination: Pagination,
},
data () {
return {
currentPage: 1,
};
},
methods: {
onPageChange(page) {
console.log(page)
this.currentPage = page;
}
},
});
Author
Alligator.io
Demo
See the Pen Pagination component by Alligator.io (@alligatorio) on CodePen.