Создайте эффективную бесконечную прокрутку для ваших приложений Vue

В веб-приложении Vue мы иногда получаем так много данных из API, которые не можем отобразить на нашем сайте сразу из-за проблем с производительностью, вместо этого мы хотим отображать их по частям.

Одна из самых сложных частей создания внешнего интерфейса - это реализация возможности управления событиями и свойствами приложения. Попытка реализовать функцию бесконечной прокрутки неправильно может повлиять на производительность приложения. Многие разработчики сталкиваются с проблемами при попытке реализовать бесконечную прокрутку со сторонними библиотеками, но некоторые из используемых библиотек или методов обычно не являются лучшим вариантом с точки зрения производительности.

API Vue Intersection Observer - это альтернатива, которая позволяет нам наблюдать изменения на пересечении целевого элемента и элемента-предка. У него также есть функция обратного вызова, которая срабатывает, если элемент попадает в область просмотра.

Как работает API Vue Intersection Observer

Этот API представляет собой компонентную библиотеку, построенную на основе собственного Javascript API. Он делает много полезных вещей, которые раньше были возможны только с помощью событий прокрутки. Вместо того, чтобы просто запускать кучу событий, он будет ждать появления цели, прежде чем запускать событие. Эти события можно использовать для отслеживания объектов, которые входят в область просмотра или покидают ее. Они также могут изменить степень отображения элемента на странице.

Настройка нашего проекта

Мы не будем использовать Vue CLI для выделения этого проекта, вместо этого мы разместим наш проект в этой codeandbox . Код доступен там, его можно разветвить и даже улучшить.

//html
<template>
<div class="p-3">
<div class="mx-auto max-w-screen-lg">
<h1>All Comments</h1>
<div class="py-4">
<div v-for="(quote, i) in quotes" :key="quote._id">
<div :class="`contain-quote ${i % 2 == 0 ? 'bg-gray-100' : ''}`">
<p class="my-5 text-lg text-center text-gray-500">
<span>"{{ quote.quoteText }}"</span><br />
<span class="text-gray-400">- {{ quote.quoteAuthor }}</span>
</p>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import axios from "axios";
export default {
name: "all",
data() {
return {
quotes: [],
};
},
methods: {
async getQuotes() {
try {
const response = await axios.get(
`https://quote-garden.herokuapp.com/api/v3/quotes?page=${this.page}`
);
// JSON responses are automatically parsed.
const data = await response.data;
this.quotes = data.data
console.log(this.quotes);
} catch (error) {
console.log(error);
}
},
},
mounted() {
this.getQuotes();
},
};
</script>

Это начальный код, который нам нужен для реализации функции бесконечной прокрутки во Vue. Позвольте мне кратко рассказать о том, что происходит в приведенном выше коде. В этом проекте мы будем использовать API с открытым исходным кодом. Наш API возвращает массив кавычек., И мы можем видеть в нашем объекте данных, что у нас есть массив комментариев, поэтому мы можем хранить массив объектов, которые мы получаем из нашего API.

У нас есть асинхронный метод getQuotes, который извлекает цитаты из нашего API и заполняет наш массив Quotes кавычками. Функция getQuotes запускается каждый раз, когда наша страница монтируется, потому что мы вызвали ее в нашей ловушке mounted. В нашем шаблоне мы перебираем массив объектов и соответственно отображаем цитату и автора цитаты.

Пакет Vue Observability

vue-observe-visibility - это пакет, который использует Intersection Observer API, чтобы упростить реализацию таких вещей, как бесконечная прокрутка на веб-сайте. Нам нужно установить его в нашем проекте, чтобы использовать его, запустив

npm install --save vue-observe-visibility

Теперь, когда он установлен, мы хотим его настроить. Для этого мы переходим к нашему main.js файлу в проекте vue и импортируем пакет, также прося Vue подтвердить и использовать стороннюю библиотеку.

import VueObserveVisibility from "vue-observe-visibility";
Vue.use(VueObserveVisibility);

Теперь у нас есть доступ к директиве v-observe-visibility в нашем приложении.

Воспроизведение сеанса с открытым исходным кодом

Отладка веб-приложения в рабочей среде может быть сложной задачей и потребовать много времени. OpenReplay - альтернатива с открытым исходным кодом для FullStory, LogRocket и Hotjar. Он позволяет вам отслеживать и воспроизводить все, что делают ваши пользователи, и показывает, как ваше приложение ведет себя при каждой проблеме. Это похоже на то, как если бы инспектор браузера был открыт, а пользователь смотрит через плечо. OpenReplay - единственная доступная альтернатива с открытым исходным кодом.

Удачной отладки, для современных команд, работающих с веб-интерфейсом - Начни мониторинг своего веб-приложения бесплатно.

Добавить бесконечную прокрутку на страницу

В нашем шаблоне под объектами, которые мы визуализируем, то есть нашими кавычками, мы создаем пустой div. В div мы установим директиву v-observe-visibility для вызова метода с именем handleInfinityScroll.

<div v-observe-visibility="handleInfinityScroll">

Есть много вещей, которые вы можете сделать, чтобы настроить этот плагин, вы можете пойти дальше и проверить документацию. В наших сценариях мы хотим сначала проверить, вызывается ли функция handleInfinityScroll, чтобы мы могли что-то записать в консоль.

methods: {
handleInfinityScroll() {
console.log("fetch more stuff");
},
},

Теперь, если мы перезагрузим наше приложение и прокрутим его вниз, мы увидим, что fetch more stuff логгируется на консоли каждый раз. *handleInfinityScroll* вызывается часто, и его вызов только тогда, когда видна нижняя часть страницы, является разумным поступком.

handleInfinityScroll(isVisible) {
if (!isVisible) {
return;
}
console.log("hehe");
},

Итак, чтобы исправить это, мы передаем аргумент isVisible и проверяем видимость нижней части страницы, используя оператор if, чтобы решить, видна ли нижняя часть страницы или нет. Мы вернемся из функции, если нижняя часть страницы не видна, и если она видна, мы снова вызываем функцию getQuotes().

Бесконечная прокрутка по страницам

<script>
import axios from "axios";
export default {
name: "all",
data() {
return {
quotes: [],
page: 1,
totalpage: 7268,
};
},
methods: {
async getQuotes() {
try {
const response = await axios.get(
`https://quote-garden.herokuapp.com/api/v3/quotes?page=${this.page}`
);
// JSON responses are automatically parsed.
const data = await response.data;
this.quotes.push(...data.data);
console.log(this.quotes);
} catch (error) {
console.log(error);
}
},
handleInfinityScroll(isVisible) {
if (!isVisible) {
return;
}
if (this.page >= this.totalpage) {
return;
}
this.page++;
this.getQuotes();
console.log("hehe");
},
},
mounted() {
this.getQuotes();
},
};
</script>

Выше довольно много всего происходит, давайте разберемся с этим. Мы видим, что мы установили состояние page в нашем объекте данных, а также общее состояние страницы, установленное на 7268. Страница, на которой мы сейчас находимся, динамически связана с нашим вызовом API, поэтому, если мы сделаем наш первоначальный запрос к API https://quote-garden.herokuapp.com/api/v3/quotes?page=${this.page}, чтобы получить котировки, мы будем получать данные для страницы 1. В методе прокрутки handleInfinityScroll после того, как мы проверим, видна ли нижняя часть страницы, мы хотим увеличить счетчик страниц и снова вызвать функцию getQuote(), которая извлекает новый набор данных цитаты для страницы 2.

this.page++;
this.getQuotes();

Мы заметили кое-что раньше, именно здесь мы устанавливаем массив кавычек, равный нашему массиву напрямую.

this.quotes = data.data

Теперь мы помещаем массив объектов в наш quotes массив наших данных каждый раз, когда getQuotes() функция повторно запускается. Мы также распределяем объекты, поэтому каждый раз, когда вызывается функция getQuotes(), мы просто продолжаем добавлять новые объекты к уже имеющимся в нашем массиве кавычек.

Зная, когда остановиться

Поскольку страница заканчивается на 7268, как указано в нашем API, мы замечаем, что, когда мы достигаем конца страницы, наш API продолжает делать запросы к страницам, которые на самом деле не существуют. Мы можем улучшить это, выполнив еще одну проверку в нашей функции handleInfinityScroll. Что мы хотим сделать, так это проверить, больше ли наша текущая страница или равна общему количеству страниц, и если она возвращает true, мы возвращаемся из функции.

if (this.page >= this.totalpage) {
return;
}

Вывод

Ура !. Мы наконец подошли к концу этого урока. Мы узнали, как использовать пакет API наблюдателя Vue для реализации бесконечной прокрутки. Надеюсь, вы сделаете больше замечательных вещей с API наблюдателя Vue. Не стесняйтесь обращаться ко мне в Twitter.

Первоначально опубликовано на https://blog.openreplay.com 15 сентября 2021 г.