Laravel

Como fazer paginação infinita com Laravel e Vue.js

Por em

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:

É isso, qualquer dúvida poste dos comentários.