Pagination Logic - Vue

Viewed 352

Hey hopefully someone can help me out, Ive started a new job and my brain has turned to utter crap and seemingly simple tasks are now causing me issues, its like I left my brain at my last job? Anyway I have some pagination that Im trying to build the logic for.

I have a v-for that loops through the data to build the pagination using the index number as the page number. I also know what page number is active and how many total pages. Im using v-if to either show or hide the pagination items. I want to show 8 items at any one time and hide the rest so if page 2 is active, items 2-9 would be shown and rest would be hidden, that part works fine. What im trying to do is when I get towards the end of the list I still want to keep 8 items on screen and the active item just advances i.e so 9 items in total, item 2 is set to active and on screen I can see items 2-9, when I click next I still want to have 8 items on screen (2-9) but now the active item is item 3 and so on. Can this be done using the v-if or am I loosing the plot and trying to achieve the impossible?

<div v-for="index in totalPages" :key="index">
              <div
                v-if="
                  index >= activeItem &&
                  index < activeItem + onScreenTotal
                "
                :class="index === activeItem ? 'active' : null"
              >
                {{ index }}
              </div>
            </div>
  • totalPages = total number of pagination items
  • activeItem = the active page item
  • onScreenTotal = how many items I want to show on screen at any one time
1 Answers

You can with some Math.min(..) and Math.max(..) calls, but your template would get really messy. I would recommend moving the logic to a computed property. You start either at the current page, or this.onScreenTotal pages before the end, with the edge case that if you have less than this.onScreenTotal pages you want to start at page 1 and not 0 or some negative number. You can calculate the end in the same way, except that we will never exceed the number of pages we have.

<template v-for="index in visiblePages">
  <div :key="index" :class="{ active: index === activeItem }">
    {{ index }}
  </div>
</template>

// And in your javascript
computed: {
  visiblePages() {
    const pages = [];
    const start = Math.max(1, Math.min(this.activeItem, this.totalPages - this.onScreenTotal));
    const end = Math.min(start + this.onScreenTotal, this.onScreenTotal);

    for (const i = start; i <= end; i++) {
      pages.push(i);
    }

    return pages;
  }
}
Related