Пагинация увеличивает UX, позволяя пользователям визуализировать данные в небольших блоках или на страницах. Вот и компонент Vue.js можно сделать с разбивкой по страницам, который позволит нам просматривать только часть наших данных за раз.

Сначала я буду добавлять кусочек за кусочком в свой JavaScript объект. А затем покажу template (шаблон)
Из всех локальных данных, мне нужны, только данные?-?номер страницы.
data(){
    return {
      pageNumber: 0  // по умолчанию 0
    }
}
Для props (свойств), передача данных является обязательной, но я также возьму size аргумент для максимального количества записей.
props:{
    listData:{
      type:Array,
      required:true
    },
    size:{
      type:Number,
      required:false,
      default: 10
    }
}
Для моей реализации я буду использовать методы для перехода на previous (предыдущую) и next (следующую) страницы:
methods:{
      nextPage(){
         this.pageNumber++;
      },
      prevPage(){
        this.pageNumber--;
      }
}
Быстрое вычисляемое свойство computed, чтобы выяснить, сколько есть страниц:
pageCount(){
      let l = this.listData.length,
          s = this.size;
      // редакция переводчика спасибо комментаторам
      return Math.ceil(l/s);
      // оригинал
      // return Math.floor(l/s);
}
Теперь вычисленное свойство (computed) paginatedData?-?это место, где все объединяется. Это отфильтрованные данные, которые будут отображаться.
paginatedData(){
    const start = this.pageNumber * this.size,
          end = start + this.size;
    return this.listData.slice(start, end);
}
Редакция: я изначально делал что-то ужасное и громоздкое, чтобы скопировать массив. Использование .slice?-?лучший подход. Спасибо, Alexander Karelas.
И наш template (шаблон)
<div>
  <ul>
    <li v-for="p in paginatedData">
      {{p.first}} 
      {{p.last}}  
      {{p.suffix}}
    </li>
  </ul>
  <button @click="prevPage">
    Previous
  </button>
  <button @click="nextPage">
    Next
  </button>
</div>
Я хочу, чтобы кнопки работали, когда они только должны. Для кнопки prevPage я добавлю:
:disabled=«pageNumber==0»а для кнопки nextPage добавлю:
:disabled=«pageNumber >= pagecount -1»Рабочая демонстрация моего компонента:
Иногда бывает трудно переоценить ситуацию, но разбиение на страницы?-?это простая функция, которую мы можем предложить нашим пользователям без особых усилий.
Спасибо за прочтение!
Denny Headrick?-?веб-разработчик USAF, который слишком сильно любит свою работу. В дополнение к разработке на различных платформах и Vue.js, когда он может, он любит вести блог изредка. Вы можете следить за ним в Twitter на @dennythecoder.
Комментарии (18)
 - c01nd01r13.07.2018 18:30- Это, скорее, виджет, который показывает страницы. Пагинация должна как-то реагировать/переключать элементы. 
 Можно хотя бы ивенты добавить.
 - VolCh14.07.2018 11:49- Общий вопрос по пагинации: если источник данных её не поддерживает, потенциальное число записей не настолько большое, чтобы клиент начал ощутимо тормозить, то есть ли вообще смысл с нею заморачиваться, пока нет жёсткого требования от бизнеса? Лично мне удобнее скроллить, например, таблицу на 1000 строк, чем страничками её листать.  - klubben14.07.2018 13:11- Полностью согласен, в 99% случаев пагинация ухудшает UX 
 Никогда не понимал зачем делать, например, список товаров по 10 штук на странице, покажите все сразу
 
 - ivolkoff15.07.2018 21:30- С vue я не понимаю одной вещи, как правильно хранить данные так что бы они были актуальны, например я гружу по ajax данные пачками, с первой страницы перешёл на вторую, а потом снова на первую. и как правильно действовать? 
 Брать данные из локального хранилища или снова ajax к серверу. Понимаю что лучше как просит бизнес. Но как вы делаете? - bad4iz Автор15.07.2018 21:34- Здесь все зависит от того что дорого… 
 если дорого запросы то локально хранить.
 Если хотим сэкономить место у пользователя то запросы.
 А еще вы не рассмотрели SPA
  - Odrin16.07.2018 11:50- Все всегда зависит от конкретной задачи. Но зачастую вместе с серверной пагинацией идет еще фильтрация/сортировка и пытаться что-то кэшировать на клиенте уже нецелесообразно, imho оптимальнее всего использовать кэш на уровне сетевого взаимодействия — get запросы отлично кешируются. 
 
 
           
 
OlehKurpiak
math.floor(5/2) = 2, хотя количество страниц должно бить 3
BerkutEagle
В примере получается целое количество страниц, поэтому ошибка не проявилась. Потом сломается, на проде!
Вот вам и пример необходимости тестов.
VolCh
Тут тесты сами по себе вряд ли бы помогли, даже со 100% покрытия. Собственно тесты — это и есть примеры использования.
RSM
Math.ceil должно быть