Пагинация — норм. Бесконечная прокрутка — зло, если ею злоупотреблять. Laravel и Vue.js позволяют прикрутить оба варианта за пять минут, но вот выбор, какой юзать, решает, будут ли юзеры материться или останутся довольны.
Скажу честно: я ненавижу бесконечную прокрутку. Вот ты ищешь инфу на сайте, уже нашёл внизу интересное, отвлёкся, вернулся — и, привет, список улетел, потому что скролл перезагрузился. Или хочешь перейти сразу на страницу 10? Да хрен тебе. Листай, как проклятый.
Но да, иногда она реально нужна — например, в фидах соцсетей, где никто не собирается прыгать по страницам. В остальных случаях — старая добрая пагинация рулит. В Laravel и Vue.js можно прикрутить и то, и то. Код простой, но давай разберём, где чаще всего косячат.
Laravel: отдаём данные порциями
Любой список постов или заказов — это paginate(). Ничего умнее и не надо:
public function index(Request $request)
{
$posts = Post::query()->paginate(10);
return response()->json($posts);
}
Маршрут:
Route::get('/posts', [PostController::class, 'index']);
Всё. На стороне Laravel это делается быстрее, чем ты откроешь очередную доку.
Vue.js: простая пагинация
В Vue пагинация — это просто кнопки «вперёд/назад» или номера страниц. Логика такая же: отправляем ?page=2, получаем данные. Всё.
<template>
<div>
<div v-for="post in posts" :key="post.id">
{{ post.title }}
</div>
<button @click="loadMore" v-if="!loading">Загрузить ещё</button>
<div v-if="loading">Загрузка...</div>
</div>
</template>
<script>
export default {
data() {
return {
posts: [],
page: 1,
loading: false
}
},
methods: {
async fetchPosts() {
this.loading = true;
const response = await fetch(`/api/posts?page=${this.page}`);
const data = await response.json();
this.posts.push(...data.data);
this.loading = false;
},
loadMore() {
this.page++;
this.fetchPosts();
}
},
mounted() {
this.fetchPosts();
}
}
</script>
Это нормальная реализация, и она юзеру даёт выбор — грузить дальше или нет.
Vue.js: бесконечный скролл
А вот тут начинается веселье. Ты вешаешь слушатель на скролл и тупо грузишь новые данные, когда пользователь доходит до конца:
handleScroll() {
const { scrollTop, clientHeight, scrollHeight } = document.documentElement;
if (scrollTop + clientHeight >= scrollHeight - 50) {
this.page++;
this.fetchPosts();
}
}
Минусы:
- баги с дублированием данных;
- жрёт память, если юзер скроллит до потери пульса;
- при обновлении страницы всё улетает к чертям.
Да, оно красиво смотрится на демо. Но на проде это превращается в боль, если юзеров тысячи.
Где чаще всего ломается
- Нет лимита. Юзеру дали возможность скроллить бесконечно → браузер начинает хавать память как не в себя.
- Нет кнопки «назад к странице N». Всё, человек матерится и закрывает сайт.
- Дублируются записи. Потому что криво проверяют, что уже загружено.
- API не оптимизировано. Запросы грузят больше данных, чем надо, и Redis/MySQL начинает задыхаться.
Итог
Laravel и Vue делают пагинацию и скролл лёгкими. Но это не вопрос «как», а вопрос «зачем». Если у тебя блог или интернет-магазин — делай нормальную пагинацию, не мучай людей. Если у тебя соцсеть или фид новостей — скролл норм.
0 комментариев