Главная » Статьи » Пагинация с помощью Vuejs

Пагинация с помощью Vuejs

Пагинация с помощью Vuejs

От автора: Vuejs — простая, но мощная среда для разработки приложений с использованием JavaScript. Попробовав Angular и поработав с несколькими приложениями React я часто говорю: «Vue может это сделать, только проще». С возможностями, которые дает простая кривая обучения, Vue действительно выделяется для меня. React и Angular содержат гораздо больше всего сразу из коробки, но если вы хотите создать управляемое данными приложение JavaScript, Vue более чем достаточно.

Теперь к пагинации. При создании веб-приложений вам придется иметь дело с представлением данных пользователям по релевантности. Так, например, в блоге вы хотите сначала отобразить последние посты. Критерии сортировки могут отличаться, но вы не можете показать весь контент на одной странице, поэтому вы разделяете его на страницы. Пагинация — это настолько общая функция веб-приложений, что я был шокирован тем, что не нашел контента, который легко клонировать в приложение, которое я создавал в то время. Мне пришлось заново изобретать колесо. В этом посте я покажу, как делается пагинация Vue js. По мере прогресса, я буду показывать вам несколько простых, но мощных концепций фреймворка.

Этот пост предполагает, что вы знакомы с основами Vuejs, но вы должны быть в состоянии следовать этому руководству, даже если просто писали какой-то JavaScript в прошлом. Мы будем отображать посты в блоге, но мы не будем создавать для этого back-end, JSON-заполнитель прикроет нам спину:). JSON-заполнитель — это Fake Online REST API for Testing and Prototyping. Мы будем получать посты оттуда и разбивать их на страницы. Чтобы быстро создать страницу, давайте возьмем красивый шаблон из Bootstrap Examples. Шаблон для примера альбома отлично подходит для меня. Чтобы сделать все быстрее, я уже внес изменения в шаблон. Клонируйте этот репозиторий на Git, и ваша страница должна выглядеть так:

Пагинация с помощью Vuejs

Затем давайте введем Vue и Axios. Axios — это библиотека JavaScript для отправки Http-запросов. Мы будем использовать ее для получения сообщений в блоге от JSON-заполнителя. Нам также нужно создать собственный файл paginate.js и ссылку на него. В нем мы напишем весь код страницы Vuejs. Вставьте этот код ниже html непосредственно перед закрывающим тегом body.

<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.18.0/axios.min.js"></script>
<script src="pagination.js"></script>

Теперь к Vue! Нам нужно указать Vuejs, какой элемент в DOM он должен контролировать. Для этого мы добавляем атрибут id в html-тег main (я предполагаю, что вы клонировали репозиторий Git). Вот так:

<main role="main" id="pagination-app">...
</main>

Затем мы инициализируем наше приложение Vue и определяем необходимые переменные данных.

const paginationApp = new Vue({ el: '#pagination-app', data: { posts: [], baseUrl: 'https://jsonplaceholder.typicode.com/', page: 1, perPage: 9, pages: [], }
});

Свойство el определяет, каким элементом будет управлять наше приложение Vue. Это будет основной html-тег, к которому мы добавили идентификатор pagination-app. Свойство data содержит все данные, которые будут использоваться в нашем приложении. posts будет содержать посты, которые мы получаем от JSON-заполнителя. Мы будем отправлять запросы к baseUrl. page — это текущая просматриваемая страницу, perPage определяет, сколько постов мы будем выводить на странице, а pages- это массив номеров страниц, которые мы будем заполнять в ближайшее время.

Идея заключается в следующем. Когда мы получаем посты, мы будем отображать первые 9, а затем, когда пользователь нажимает номер страницы, мы будем отображать посты, присвоенные этому номеру страницы. Итак, первые 9 постов находятся на странице 1, следующих 9 на странице 2 и так далее. В DOM мы затем переберем эти посты так:

<!-- Перебираем через цикл displayedPosts, чтобы вывести каждый пост--> <div class="container"> <div class="row"> <div class="col-md-4" v-for="post in displayedPosts"> <div class="card mb-4 box-shadow post-cards"> <div class="card-body"> <h5 class="capitalize">{{post.title}}</h5> <p class="card-text">{{post.body.slice(0, 120)}}...</p> </div> </div> </div> </div> <!-- Перебираем через цикл массив pages, чтобы вывести каждый номер страницы --> <div class="clearfix btn-group col-md-2 offset-md-5"> <button type="button" class="btn btn-sm btn-outline-secondary" v-if="page != 1" @click="page--"> << </button> <button type="button" class="btn btn-sm btn-outline-secondary" v-for="pageNumber in pages.slice(page-1, page+5)" @click="page = pageNumber"> {{pageNumber}} </button> <button type="button" @click="page++" v-if="page < pages.length" class="btn btn-sm btn-outline-secondary"> >> </button> </div> </div>

Обратите внимание, что мы перебираем displayedPosts, который является вычисляемым свойством, которое мы еще не объявили. Вычисляемые свойства полезны, когда вам нужно манипулировать данными перед их отображением в представлении. Мы также перебираем массив pages, чтобы вывести каждый номер страницы. Теперь давайте извлечем посты из JSON-заполнителя с помощью Axios.

const paginationApp = new Vue({ el: '#pagination-app', data: { posts: [], baseUrl: 'https://jsonplaceholder.typicode.com/', page: 1, perPage: 9, pages: [], }, methods: { getPosts () { axios.get(this.baseUrl+'posts') .then(response => { this.posts = response.data; }) .catch(response => { console.log(response); }); } }, created () { this.getPosts(); }
});

Мы используем Axios для отправки запроса на получение https://jsonplaceholder.typicode.com/posts. Мы немедленно вызываем функцию getPosts, и наша страница создается с использованием хука цикла created, который Vuejs предоставляет нам, а затем, получив посты в качестве ответа, мы установим их в свойство данных posts, которое мы определили ранее. JSON-заполнитель возвращает 100 постов, поэтому нам нужно разбить их на страницы. Количество страниц будет зависеть от количества сообщений, которые мы получаем.

Теперь мы заполним массив pages требуемыми номерами страниц в зависимости от количества постов. Для этого мы установили то, что в Vuejs называется watcher. Это функции, которые запускаются при изменении свойств данных. Мы будем наблюдать за свойством posts, так как оно устанавливается в методе getPosts, оно используется для заполнения массива pages.

const paginationApp = new Vue({ el: '#pagination-app', data: { posts: [], baseUrl: 'https://jsonplaceholder.typicode.com/', page: 1, perPage: 9, pages: [], }, methods: { getPosts () { axios.get(this.baseUrl+'posts') .then(response => { this.posts = response.data; }) .catch(response => { console.log(response); }); }, setPages () { let numberOfPages = Math.ceil(this.posts.length / this.perPage); for (let index = 1; index <= numberOfPages; index++) { this.pages.push(index); } }, }, created () { this.getPosts(); }, watch: { posts () { this.setPages(); } }
});

Из watcher posts мы вызываем метод setPages. Цикл for в setPages заполняет массив страниц числами от 1 до количества страниц, которые нам нужно создать.

Теперь нам нужен способ определить, какие посты будут отображаться на основе текущего номера страницы. Затем мы вернем эти сообщения в нашем вычисляемом свойстве displayedPosts.

const paginationApp = new Vue({ el: '#pagination-app', data: { posts: [], baseUrl: 'https://jsonplaceholder.typicode.com/', page: 1, perPage: 9, pages: [], }, methods: { getPosts () { axios.get(this.baseUrl+'posts') .then(response => { this.posts = response.data; }) .catch(response => { console.log(response); }); }, setPages () { let numberOfPages = Math.ceil(this.posts.length / this.perPage); for (let index = 1; index <= numberOfPages; index++) { this.pages.push(index); } }, paginate (posts) { let page = this.page; let perPage = this.perPage; let from = (page * perPage) - perPage; let to = (page * perPage); return posts.slice(from, to); } }, created () { this.getPosts(); }, watch: { posts () { this.setPages(); } }, computed: { displayedPosts () { return this.paginate(this.posts); } }, });

Мы вызываем метод paginate из вычисляемого свойства displayPosts. Раньше мы привязали событие click к каждому отображаемому номеру страницы. Событие click задает свойство данных страницы для номера страницы, на котором кликнул пользователь. Поскольку Vuejs является реактивным, вычисляемое свойство displayPosts подвергается повторной оценке каждый раз, когда свойство данных страницы изменяется из события click.

Метод paginate разбивает массив posts на основе текущего номера страницы и количества постов perPage. Итак, для страницы 1 он возвращает посты с 0 по 8, для страницы 2 — с 9 по 17 и так далее. Таким образом, мы не напрямую манипулируем DOM для изменения страницы, мы просто меняем отображаемые данные.

Это отличная демонстрация свободы и элегантности, которые предоставляет Vuejs. Пагинация — одна из проблем, которую я смог решить, потому что мой фреймворк был ограничен в гибкости и творчестве мышления, хотя предлагал чрезвычайно мощные инструменты. Вы можете найти полный рабочий код для этого руководства в репозитории на Git. Вы можете настроить его под собственные потребности. Здесь вы также можете найти рабочую демонстрацию. Спасибо за прочтение.

Автор: Emmanuel

Источник: https://medium.com/

Редакция: Команда webformyself.