Frontend moderno senza toccare una riga di javascript
26 Novembre 2020
di Alessandro Cappellozza
BLADE
LIVEWIRE
FRAMEWORK.JS
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
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
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
Scaletta
BUS
Componente
Componente
Componente
Componente
Browser
Server
Event Emitter
Lo stato e mantenuto solo dalle proprietà public e solo di una certa tipologia:
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
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
alessandro.cappellozza@gmail.com
https://github.com/eppak
Github
Disegni https://undraw.co/
https://joind.in/talk/ca018
Joind
Mauro Gallo, Marco Sottana, Roberto Gallea
Ringraziamenti
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.
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>
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>
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');
}
}
https://en.wikipedia.org/wiki/Model-view-viewmodel
https://github.com/spatie/laravel-view-models