LiveWire

Hands on

Frontend moderno senza toccare una riga di javascript

26 Novembre 2020

di Alessandro Cappellozza

COs'è

  • Package per Laravel 7+
  • Versione 2.x
  • Integrabile su nuovo e pregresso
  • Licenza Mit
  • SSR basato su Blade

 

BLADE

LIVEWIRE

FRAMEWORK.JS

  • Semplice e statico
  • Interazioni basate su verbi http
  • Pronto out of the box
  • SSR
  • Componenti
  • Azioni
  • Casi classici
  • Databinding
  • Si integra coi microservizi
  • Separazione Ui/Be
  • Vasta scelta di librerie e package

Punto di vista Backend

Per quelli a cui non piace troppo context switch (?)

In un'ottica di sviluppo "blade based" ci atteniamo ad un modello che sfrutta gli strumenti out of the box rendendo però l'interfaccia meno fruibile e legata ad una gestione dei verbi come azioni e querystring/sessione come stato.

(es. 2 package manager)

JavaScript
mix
npm
2 repo

Principio di funzionamento

Browser
(COMPONENTE)
SERVER
(Blade/LIVEWIRE)

Evento

Risposta SSR

Le indicazioni comportamentali vengono assegnate con un TAG
php artisan livewire:make MyComponent
resources/view/livewire/my-component.blade.php
app/Http/Livewire/MyComponent.php

Principio di funzionamento

La chiamata asincrona risponde con html e lo inietta direttamente nel dom
hover del mouse
php artisan make:model Product --migration
php artisan make:factory Product
php artisan migrate:fresh --seed
php artisan livewire:make Products
php artisan livewre:make ProductRow
php artisan livewire:make Notifier

Proviamo a creare un modello prodotti e a fare una griglia di ricerca paginata con possibilità di un edit inline

Esempio Pratico

Live coding

Scaletta

EVENT BUS

BUS

Componente

Componente

Componente

Componente

Browser

Server

Event Emitter

ASPETTI CHIAVE

Lo stato e mantenuto solo dalle proprietà public e solo di una certa tipologia:

 

  • Number
  • String
  • Array
  • Boolean
  • Model
  • Collection

Il constructor è a disposizione solo del framework al suo posto è presente mount dove è presente dependency injection come anche nelle azioni.

Stato del Componente

Dependency Injection

ACTION Delegation

class MyComponent extends Component
{
    public $variable;
    
    public $reference;    

    public function action(UpdateAction $action)
    {
        $action->update(
            $this->variable,
            $this->reference
        );
    }

    public function render()
    {
        return view('some.view');
    }
}
class UpdateAction
{
    public function update($variable, $ref)
    {
        Gate::forUser($ref)
        	->authorize('updateAction', $ref);

		// Action...
    }
}
Le rotte vengono sostituite in maniera semplice dalle azioni

PITFALLS

  • Tipi di proprietà pubblica vincolata a tipi JS compatibili, modelli/collezioni
  • Mancanza di stato per tutto quello che non è una proprietà pubblica
  • Parole chiave rigide (es. wire:click compie una sola azione)
  • Limitato ad casi d'uso specifici (es. drag & drop)
  • Carico sul server (non è una API)
  • Suscita sentimenti duali

Ringraziamenti e Riferimenti

alessandro.cappellozza@gmail.com

https://github.com/eppak

Email

Github

Disegni https://undraw.co/

https://joind.in/talk/ca018

Joind

Mauro Gallo,
Marco Sottana,
Roberto Gallea

Ringraziamenti

APPROFONDIMENTI

Orientamento al componente

Se nei controller si ha il pericolo di inserirci logica, qui si rischia di metterla nel componente, soprattutto essendo legato ad eloquent.

 

E' necessario cercare delle strategie di mantenimento e struttura del codice.

Estensibilità ed ECOSISTEMA

  • Riferimento integrato
  • AlpineJS
  • Integrazione di librerie js
  • Componenti (es. datatables)

SPA

Route::get('/product/{product}', 
                       Product::class);

class Product extends Component
{
    public $product;

    public function mount(Product $product)
    {
        $this->product= $product;
    }

    public function render()
    {
        return view('product')
        	->layout('layout');
    }
}
<html>
<head>
@livewireStyles
</head>
<body class="bg-light">

 <div class="container">

  <div class="py-5 text-center">
    <h2>SPA</h2>
  </div>
  
	{{ $slot }}
    
 </div>

@livewireScripts
</body>
</html>

POLLING

Il web per sua natura è "passivo" oltre che stateless, sono a disposizione delle direttive per effettuare refresh automatici.


Sono messe a disposizione delle ottimizzazioni per diminuire la banda, questo però non diminuisce il carico sul server.
<div wire:poll.250ms>
    ..
</div>

<div wire:poll="action">
    ..
</div>

<div wire:poll.keep-alive>
    ..
</div>

POLLING: Chat

Questo è uno degli scenari peggiori per un polling perché non possiamo lavorare su eveti in push.

 

Unendo al polling l'event dispatcher possiamo realizzare .

(ma a che prezzo?)
<div wire:poll.1000ms="check">
    Refresh...
</div>

class Messages extends Component
{

    public function check(Messages $messages)
    {
    	if($messages->unread()) {
        	$this->emit('updateMessages');
        }
    }

    public function render()
    {
        return view('notifier');
    }
}

Un approccio strutturato: MMVM

https://en.wikipedia.org/wiki/Model-view-viewmodel
https://github.com/spatie/laravel-view-models
Made with Slides.com