Thiago Cantero

Tecnologia e Entretenimento

Arquitetura de SoftwareLaravelLivewirePadrões de ProjetoPHP

Componentização com Laravel + Livewire

Olá, mundo!
Tudo bem?

Quando optamos por uma Stack de desenvolvimento, como a adoção do ReactJS, VueJS, Angular ou qualquer outra boa nova das bibliotecas Javascript que existem no mercado, nos deparamos com alguns problemas, em certos cenários, muito oneroso, e extramente caro.
Muitas aplicações corporativas são monolíticas, ou seja estão dispostas em uma única instância provendo todas as camadas da aplicação. (Farei uma postagem sobre as diferenças entre uma Aplicação Monolítica e uma Aplicação orientada aos Microserviços). Fato é que os componentes nos ajudam na produtividade na elaboração do Código, além de servir para uma boa interação do Usuário com a aplicação. É óbvio que devemos ter atenção os quesitos de segurança, isto é completamente notório e evidente, a adoção também da biblioteca, o fará – dependendo da stack – um forte acoplamento, o que em um futuro será uma dor de cabeça na manutenção deste código.

Existem outros Frameworks no Mercado, como o Django (Python), Prado (PHP), Thymeleaf (Java), Razor (C#), enfim uma infinidades de ferramentas e Templates Engines que existem no mercado!Auxiliam na elaboração da camada de interface com o usuário, injetando HTML e sua linguagem atuando no backend, trazendo informações do seu banco de dados. Este padrão de Arquitetura de Software está no Catalogo de Martin Fowler, em Padrões de Arquitetura de Aplicações Corporativas, e seu nome é o Template View.

A idéia básica da Template View é inserir marcadores em uma página HTML estática quando ela é escrita. Quando a página é usada para atender uma solicitação, os marcadores são substituídos pelo resultado de alguma computação, como uma pesquisa em um banco de dados. Dessa forma a página pode ser mostrada do modo costumeiro, muitas vezes com editores WYSWYG, muitas vezes por pessoas que não são programadoras. Os marcadores então se comunicam com programas reais para enviar os resultados. – Padrões de Arquiteturas de Aplicações Corporativas, pág. 333, Martin Fowler, Editora Bookman 2006

Esquema Obtido na Obra de Martin Fowler

Como sempre, Martin Fowler bem pontual em suas explanações com bons exemplos.

Vamos ao Trabalho\\

No Laravel há um pacote, além da Template Engine Blade, que faz a inclusão de reatividade com Javascript e alteração no DOM (Document Object Model), com o próprio PHP, atuando com um Wrapper trazendo comportamentos que atendam uma necessidade, como um campo de pesquisa que autocomplete com o texto digitado, uma datatable, uma exclusão de um elemento de uma lista, etc.

Iniciaremos o nosso projeto:

$ composer create-project laravel/laravel laravel-livewire

Façamos a edição de nosso arquivo de ambiente .env

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=laravel_livewire
DB_USERNAME=<usuário do seu banco de dados>
DB_PASSWORD=<senha do seu banco de dados>

Criamos nossa base, neste caso usei o MariaDB (um fork do MySQL).

Após a criação do banco de dados, vamos executar nossa migração:

$ php artisan migrate

Agora vamos instalar nosso componente Livewire:

composer require livewire/livewire

Nosso próximo passo é a criação, por meio de nossa factory de usuários fictícios.

$ php artisan tinker

No console Tinker, façamos a chamada do Model User desta maneira:

User::factory()->count(100)->create()

Com isto, iremos criar 100 usuário em nossa base.

Agora, vamos criar nosso componente que fará uma listagem dos usuário, com paginação.

$php artisan make:livewire user-pagination

Com este Comando do Artisan, foram criados dois arquivos: app/Http/Livewire/UserPagination.php e resources/views/livewire/user-pagination.blade.php a adoção deste tipo de nomenclatura em inglês, é amplamente utilizada para melhor organização do código, como podemos ver ele já criou um arquivo em CamelCase de nosso componente.

Vamos para a edição de nosso Componente:

app/Http/Livewire/UserPagination.php

<?php

namespace App\Http\Livewire;

use Livewire\Component;
use Livewire\WithPagination;
use App\Models\User;

class UserPagination extends Component
{
    use WithPagination;
    
    public function render()
    {
        return view('livewire.user-pagination', [
            'users' => User::paginate(10),
        ]);
    }
}

Como podemos observar, a nossa classe importa a biblioteca Livewire (Livewire\Component), o componente que será usuado (Livewire\WithPagination) e nossa Model User (App\Models\User).

O Componente herda da Classe Abstrata, e logo no início faz a chamada dele com o “use WithPagination”, posteriormente no método render() ele retorna a view (criada pelo artisan), e referencia a model com array associativo, com o método estático paginate que está setado para demonstrar 10 registros por página.

Vamos criar a interface para nossa paginação.

resources/views/livewire/user-pagination.blade.php

<div>
    <table class="table-auto" style="width: 100%;">
      <thead>
        <tr>
          <th class="px-4 py-2">ID</th>
          <th class="px-4 py-2">Nome</th>
          <th class="px-4 py-2">Email</th>
        </tr>
      </thead>
      <tbody>
        @foreach ($users as $user)
            <tr>
            <td class="border px-4 py-1">{{ $user->id }}</td>
            <td class="border px-4 py-1">{{ $user->name }}</td>
            <td class="border px-4 py-1">{{ $user->email }}</td>
            </tr>
        @endforeach
      </tbody>
    </table>
  
    {{ $users->links() }}
</div>

Por padrão no Laravel, o Tailwind CSS é adotado, no entanto, aqui estamos fazendo uma chamada com diretivas do Blade (Engine HTML do Laravel).

Vamos editar nossa rota para fazer a chamada nesta classe:

Route::get('index', function () {
    return view('index');
});

E por fim nossa View que irá demonstrar o funcionamento de nosso componente.

<!DOCTYPE html>
<html>
<head>
    <title>Exemplo de Componentização Laravel + Livewire</title>
    @livewireStyles
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/tailwindcss/1.9.0/tailwind.min.css"/>
</head>
<body>    
<div class="container">    
    <div class="card">
      <div class="card-header">
      Exemplo de Componentização Laravel + Livewire
      </div>
      <div class="card-body">
        @livewire('user-pagination')
      </div>
    </div>        
</div>    
</body>  
@livewireScripts  
</html>

Como podemos observar, a diretiva @livewire é usada para injetar, na div “card-body” nosso componente, e abaixo novamente é realizada a chamada da @livewireScripts, um outro wrapper contendo os assets em Javascript para dar as funcionalidades e interações do componente.

Por hoje é isso, espero que tenha ajudado a entender como os componentes funcionam e como podem ser adotados.

; )

Código Fonte no Github.

 

O caráter é o produto da série de atos dos quais se é o princípio.