Skip to content

Instantly share code, notes, and snippets.

@Cannonb4ll
Created May 27, 2019 09:25
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Cannonb4ll/b511f3b129c590f2598876f832ae9587 to your computer and use it in GitHub Desktop.
Save Cannonb4ll/b511f3b129c590f2598876f832ae9587 to your computer and use it in GitHub Desktop.
VueJS pagination
<template>
<renderless-pagination :data="data" :limit="limit" v-on:pagination-change-page="onPaginationChangePage">
<ul class="pagination" v-if="computed.total > computed.perPage" slot-scope="{ data, limit, computed, prevButtonEvents, nextButtonEvents, pageButtonEvents }">
<li class="page-item pagination-prev-nav" v-if="computed.prevPageUrl">
<a class="page-link" href="#" aria-label="Previous" v-on="prevButtonEvents">
<slot name="prev-nav">
<span aria-hidden="true">&laquo;</span>
<span class="sr-only">Previous</span>
</slot>
</a>
</li>
<li class="page-item pagination-page-nav" v-for="(page, key) in computed.pageRange" :key="key" :class="{ 'active': page == computed.currentPage }">
<a class="page-link" href="#" v-on="pageButtonEvents(page)">{{ page }}</a>
</li>
<li class="page-item pagination-next-nav" v-if="computed.nextPageUrl">
<a class="page-link" href="#" aria-label="Next" v-on="nextButtonEvents">
<slot name="next-nav">
<span aria-hidden="true">&raquo;</span>
<span class="sr-only">Next</span>
</slot>
</a>
</li>
</ul>
</renderless-pagination>
</template>
<script>
import RenderlessPagination from './RenderlessPagination.vue';
export default{
props: {
data: {
type: Object,
default: () => {}
},
limit: {
type: Number,
default: 0
}
},
methods: {
onPaginationChangePage (page) {
this.$emit('pagination-change-page', page);
}
},
components: {
RenderlessPagination
}
}
</script>
<script>
export default {
props: {
data: {
type: Object,
default: () => {}
},
limit: {
type: Number,
default: 0
}
},
computed: {
isApiResource () {
return !!this.data.meta;
},
currentPage () {
return this.isApiResource ? this.data.meta.current_page : this.data.current_page;
},
firstPageUrl () {
return this.isApiResource ? this.data.links.first : null;
},
from () {
return this.isApiResource ? this.data.meta.from : this.data.from;
},
lastPage () {
return this.isApiResource ? this.data.meta.last_page : this.data.last_page;
},
lastPageUrl () {
return this.isApiResource ? this.data.links.last : null;
},
nextPageUrl () {
return this.isApiResource ? this.data.links.next : this.data.next_page_url;
},
perPage () {
return this.isApiResource ? this.data.meta.per_page : this.data.per_page;
},
prevPageUrl () {
return this.isApiResource ? this.data.links.prev : this.data.prev_page_url;
},
to () {
return this.isApiResource ? this.data.meta.to : this.data.to;
},
total () {
return this.isApiResource ? this.data.meta.total : this.data.total;
},
pageRange () {
if (this.limit === -1) {
return 0;
}
if (this.limit === 0) {
return this.lastPage;
}
var current = this.currentPage;
var last = this.lastPage;
var delta = this.limit;
var left = current - delta;
var right = current + delta + 1;
var range = [];
var pages = [];
var l;
for (var i = 1; i <= last; i++) {
if (i === 1 || i === last || (i >= left && i < right)) {
range.push(i);
}
}
range.forEach(function (i) {
if (l) {
if (i - l === 2) {
pages.push(l + 1);
} else if (i - l !== 1) {
pages.push('...');
}
}
pages.push(i);
l = i;
});
return pages;
}
},
methods: {
previousPage () {
this.selectPage((this.currentPage - 1));
},
nextPage () {
this.selectPage((this.currentPage + 1));
},
selectPage (page) {
if (page === '...') {
return;
}
this.$emit('pagination-change-page', page);
}
},
render () {
return this.$scopedSlots.default({
data: this.data,
limit: this.limit,
computed: {
isApiResource: this.isApiResource,
currentPage: this.currentPage,
firstPageUrl: this.firstPageUrl,
from: this.from,
lastPage: this.lastPage,
lastPageUrl: this.lastPageUrl,
nextPageUrl: this.nextPageUrl,
perPage: this.perPage,
prevPageUrl: this.prevPageUrl,
to: this.to,
total: this.total,
pageRange: this.pageRange
},
prevButtonEvents: {
click: (e) => {
e.preventDefault();
this.previousPage();
}
},
nextButtonEvents: {
click: (e) => {
e.preventDefault();
this.nextPage();
}
},
pageButtonEvents: page => ({
click: (e) => {
e.preventDefault();
this.selectPage(page);
}
})
});
}
}
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment