I am practicing vue and I am trying to build a pagination with Rick Morty Api https://rickandmortyapi.com/documentation/
Currently looks like:
I would like to display these buttons in this form 1 2 3 4 5 ... 20
if I click on 20, then it would look like 1 ... 15 16 17 18 19 20
. How can I achieve this? Do I need to use css for this, or pure js and use computed property?
<div class="button_container">
<button @click="pageChange(i 1)" v-for="(item, i) in pages" :key="i">
{{ i 1 }}
</button>
</div>
CodePudding user response:
it's not that straight forward to do it in a one-liner, the approach I would recommend is to use a computed
you could use the function from https://stackoverflow.com/a/67658442/197546
// define method
function paginate(current_page, last_page, onSides = 3) {
// pages
let pages = [];
// Loop through
for (let i = 1; i <= last_page; i ) {
// Define offset
let offset = (i == 1 || last_page) ? onSides 1 : onSides;
// If added
if (i == 1 || (current_page - offset <= i && current_page offset >= i) ||
i == current_page || i == last_page) {
pages.push(i);
} else if (i == current_page - (offset 1) || i == current_page (offset 1)) {
pages.push('...');
}
}
return pages;
}
// then in component...
data:{
return{
pages:[...],
currentPage: 0,
}
},
//...
computed: {
pageNums = () {
return paginate(this.currentPage, this.pages.length, 4)
}
}
then, because the ...
should not have an event listener, you can use <template>
and v-if
to use different element
<div class="button_container">
<template v-for="pageNum in pages" :key="i">
<button v-if="Number.isInteger(pageNum)" @click="currentPage = i">
{{ pageNum }}
</button>
<span v-else>
{{ pageNum }}
</span>
</template >
</div>