Laravel
Como fazer paginação infinita com Laravel e Vue.js
Uma das features mais amadas do desenvolvimento moderno é a paginação infinita, com ela podemos criar aplicativos quem sempre mostram mais conteúdos a medida que o usuário rola a página, sem que ele precise tomar a decisão de clicar em links.
Vantagens e Desvantagens
Eu sempre digo que 90% das decisões em cima do desenvolvimento de um aplicativo web, mobile ou desktop parte de outros fatores que NÃO SÃO técnicos, por isso esse tópico do artigo pode não refletir a sua realidade, mas eu vou me esforçar.
Um exemplo incrível sobre o uso de paginação infinita é o Google, mas ai você indaga: “Nossa, o Google não usa paginação infinita”. Verdade! E isso é bem legal, porque o Google:
- É um dos maiores em tecnologia do mundo
- Valoriza usabilidade
Estes são pontos fortes e que justificariam o Google a usar ou até inovar em paginação infinita, mas o motivo da técnica não estar presente no site do buscador pode ser um contraponto interessante: Lucro
Claro que eu estou especulando, mas acho um exemplo muito bom, apenas gostaria de deixar isso claro antes de qualquer coisa.
Eu sou do tipo de pessoa que usa o Google largamente e não passo NUNCA da primeira página, ou está nos primeiros resultados ou nem vejo, mas o mais interessante é que eu não sou o único, a grande maioria do público que faz pesquisas para nos primeiros resultados e isso gera valor, acho que o grande motivo da paginação do Google ser no mesmo modelo desde o início é simplesmente para gerar valor, já que vai diminuir drasticamente a exibição de qualquer um da segunda página para frente.
Mas outro contra-ponto é o histórico de navegação, porque você não precisa “navegar” para outra página, os dados vão vindo dinâmicamente, quando você abre um link e volta para a listagem o estado dela é o iniciante, ou seja, apenas os primeiros registros, imagine que você já tinha avançado na listagem por um tempo, pode ser irritante.
O Facebook resolve esse problema exibindo o conteúdo sobre a listagem em vez de mudar a página, é uma solução elegante e que o público está acostumado, mas você precisa lidar com isso. Aqui no artigo eu vou dar o passo inicial e implementar um Vue Component que carrega os dados da listagem, mas você ainda vai precisar lidar com isso. Dado o óbvio limite de tamanho do artigo, vou deixar isso como exercício pra você.
Colocando a mão na massa
A primeira coisa que vamos precisar, obviamente, é de uma paginação configurada no Laravel, como estou começando sem um projeto base, vou descrever os passos para criarmos tal recurso:
Primeiramente vamos instalar o Laravel:
composer create-project laravel/laravel --prefer-dist .
Agora vou configurar o banco de dados, vou usar o SQlite, mas você pode usar o que preferir, meu `.env`:
APP_NAME=Laravel APP_ENV=local APP_KEY=base64:I/sIIgsHedUUw+lWWRctHuF/ir1Gt8kgkY3rSAJcvls= APP_DEBUG=true APP_URL=http://localhost LOG_CHANNEL=stack DB_CONNECTION=sqlite BROADCAST_DRIVER=log CACHE_DRIVER=file QUEUE_CONNECTION=sync SESSION_DRIVER=file SESSION_LIFETIME=120 REDIS_HOST=127.0.0.1 REDIS_PASSWORD=null REDIS_PORT=6379 MAIL_DRIVER=smtp MAIL_HOST=smtp.mailtrap.io MAIL_PORT=2525 MAIL_USERNAME=null MAIL_PASSWORD=null MAIL_ENCRYPTION=null PUSHER_APP_ID= PUSHER_APP_KEY= PUSHER_APP_SECRET= PUSHER_APP_CLUSTER=mt1 MIX_PUSHER_APP_KEY="${PUSHER_APP_KEY}" MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}"
E vou criar o arquivo para banco de dados, é apenas um arquivo vazio, no Linux, MacOS ou clientes de linha de comando como GitBash e afins eu uso o comando `touch`, mas o importante é SER UM ARQUIVO VAZIO:
touch database/database.sqlite
Também vou criar alguns dados falsos para minha paginação e isso inclui criar um arquivo de seed (que irá criar meus dados falsos):
php artisan make:seed UsersTableSeeder
Ativar descomentando a linha 15 do arquivo database/seeds/DatabaseSeeder.php, mais especificamente, descomentar esta linha do arquivo:
// $this->call(UsersTableSeeder::class);
E no método run do arquivo criado (database/seeds/UsersTableSeeder.php) adicionar o factory:
factory(\App\User::class, 100)->create();
Neste exemplo, estou criando 100 registros, mais que o suficiente para o exemplo.
Crie o banco de dados com os arquivos falsos:
php artisan migrate --seed
Se der tudo certo, você terá 3 tabelas no banco:
- migrations
- password_resets
- users
E 100 registros na tabela users.
Criando listagem de dados paginados
O próximo passo é paginarmos os dados, claro que com Laravel não poderia ser mais simples, precisaremos de um controller, configurar a rota e fazer o Laravel paginar os registros, é bem simples.
Vamos criar o controller:
php artisan make:controller UsersController
Vamos configurar a rota, para isso abra o arquivo routes/web.php e adicione a nova rota:
Route::get('/users', 'UsersController@index');
Para os mais informados, já está mais que definido que precisamos criar um método (vulgo action) no controller criado no passo anterior, meu controller final, já com paginação:
<?php namespace App\Http\Controllers; use Illuminate\Http\Request; class UsersController extends Controller { public function index() { $users = \App\User::paginate(); return view('users', compact('users')); } }
Pode parecer que eu fiz muito, mas leve em conta que eu instalei o Laravel, configurei banco de dados, criei 100 registros e retornei isso paginado para um arquivo de view, antes de testar, vamos criar nosso arquivo de visualização.
Adicione um arquivo chamado users.blade.php no diretório resources/view com o conteúdo a seguir:
https://gist.github.com/erikfig/55649e6d460f5818a89cec45e9fe1ee3#file-users-blade-php
Ai também temos o arquivo InfiniteScroll.vue, ignore por hora.
Acesse a url http://localhost:8000/users para visualizar.
No Laravel, já resolvi tudo, vamos para o front.
Configurando o Vue.js
Nesse ponto, vamos usar os recursos que já estão disponíveis no esqueleto do Laravel, para tal, apenas rode:
npm install
E pronto.
Crie um arquivo vazio em resources\js\components\InfiniteScroll.vue e registro no arquivo resources\js\app.js adicionando o seguinte na linha 20, quero dizer, logo após Vue.component(‘example-component’, require(‘./components/ExampleComponent.vue’));
Vue.component('infinite-scroll', require('./components/InfiniteScroll.vue'));
Isso vai adicionar o componente que vamos desenvolver no arquivo rescém criado dentro de uma tag <infinite-scroll/>, isso será responsável por fazer a paginação infinita, minha ideia é que essa tag encapsule uma possível paginação que você já tenha, assim podemos manter um versão “noscript” e dar ao componente alta capacidade de personalização e usabilidade.
Criando o componente
O componente tem uma estrutura e métodos um pouco elaborados, então eu dividi tudo em 4 partes, esqueleto e os 3 métodos responsáveis pelo motor da paginação.
Eu comentei tudo e espero que tenha ficado claro, ai segue o conteúdo do arquivo InfiniteScroll.vue, apenas adicione ao que criamos no diretório components.
https://gist.github.com/erikfig/55649e6d460f5818a89cec45e9fe1ee3#file-infinitescroll-vue
Você vai notar que eu adicionei 3 métodos no item methods do arquivo, eles estão em branco, apenas com comentários para sabermos o que eles vão fazer, segue o conteúdo dos métodos:
https://gist.github.com/erikfig/f08a7bdc2afe8876583d9acc02e689d7
E com isso temos nossa paginação infinita.
Uma dica, você pode adicionar uma propriedade com uma string vazia de valor padrão para consulta das próximas páginas, assim consegue reaproveitar melhor o web component.
https://gist.github.com/erikfig/422fbc7ab45d531d94e347c1eda2a287
E aqui o InfiniteScroll.vue finalizado:
https://gist.github.com/erikfig/90964b668d2784455d2ae60f1cab53f5
Se você quiser ver mais detalhes de como trabalhar com Laravel e Vue.js integrados, veja estes dois cursos:
- https://www.schoolofnet.com/curso-vuejs-com-laravel-54/
- https://www.schoolofnet.com/curso-vuejs-com-laravel-avancado/
É isso, qualquer dúvida poste dos comentários.