Vai al contenuto principale

Cos’è Livewire

Fino a poco tempo fa, per creare UI dinamiche in Laravel bisognava affiancare un framework JavaScript come Vue.js o React, oppure scrivere direttamente richieste AJAX. Livewire è il pacchetto per Laravel che risolve questo problema. Con solo PHP e Blade puoi costruire UI reattive. Validazione in tempo reale dei form, ricerca live, contatori e simili: funzioni che tradizionalmente richiedevano JavaScript possono essere implementate interamente in PHP.
Livewire 4 gira su Laravel 10 o superiore e PHP 8.1 o superiore. La versione più recente è Livewire 4.

Panoramica del funzionamento

Un componente Livewire è la combinazione di una classe PHP lato server e di un template Blade. Quando l’utente clicca un pulsante o compila un form, Livewire invia dietro le quinte una richiesta AJAX, esegue PHP e riflette nella pagina solo le parti modificate. Lo sviluppatore può scrivere solo in PHP senza preoccuparsi del meccanismo.

Installazione

Nella directory root dell’applicazione Laravel esegui il comando seguente.
composer require livewire/livewire
Il rilevamento automatico dei pacchetti di Laravel è attivo, quindi non serve alcuna configurazione aggiuntiva.

Creazione del layout

Per usarlo come componente a pagina intera è necessario un file di layout. Puoi generarlo con il comando Artisan seguente.
php artisan livewire:layout
Viene generato resources/views/layouts/app.blade.php.
<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">

        <title>{{ $title ?? config('app.name') }}</title>

        @vite(['resources/css/app.css', 'resources/js/app.js'])

        @livewireStyles
    </head>
    <body>
        {{ $slot }}

        @livewireScripts
    </body>
</html>
@livewireStyles e @livewireScripts caricano automaticamente gli asset di Livewire e Alpine.js.

Il primo componente

Per generare un componente Livewire c’è un comando Artisan. Proviamo a creare un semplice contatore.
php artisan make:livewire Counter
Il comando genera un componente single-file chiamato resources/views/components/⚡counter.blade.php.
Il ⚡ nel nome del file serve a identificare a colpo d’occhio un componente Livewire. Migliora la leggibilità nell’editor. Se non ti serve puoi disabilitarlo nelle impostazioni.
Modifica il file generato come segue.
<?php

use Livewire\Component;

new class extends Component {
    public int $count = 0;

    public function increment(): void
    {
        $this->count++;
    }

    public function decrement(): void
    {
        $this->count--;
    }
};
?>

<div>
    <h1>Conteggio: {{ $count }}</h1>

    <button wire:click="increment">+1</button>
    <button wire:click="decrement">-1</button>
</div>
Per incorporare il componente in un template Blade usa la normale sintassi dei componenti Blade.
<livewire:counter />
Ogni clic aggiorna il conteggio senza ricaricare la pagina. wire:click è il meccanismo che, al posto del JavaScript, richiama un metodo PHP.

Proprietà e azioni

Proprietà — wire:model

Con la direttiva wire:model puoi effettuare il binding bidirezionale tra un elemento di input e una proprietà del componente.
<?php

use Livewire\Component;

new class extends Component {
    public string $name = '';
    public string $email = '';
};
?>

<div>
    <input type="text" wire:model="name" placeholder="Nome">
    <input type="email" wire:model="email" placeholder="Email">

    <p>Ciao {{ $name }} ({{ $email }})</p>
</div>
Per impostazione predefinita wire:model si sincronizza con il server solo all’esecuzione di un’azione (invio del form, ecc.). Se vuoi sincronizzare a ogni input, aggiungi il modificatore .live.
SintassiComportamento
wire:modelSincronizza solo all’esecuzione di un’azione (invio form, ecc., predefinito)
wire:model.liveInvia una richiesta a ogni input
wire:model.blurSincronizza alla perdita del focus (nessuna richiesta)
wire:model.live.blurInvia una richiesta alla perdita del focus

Azioni — wire:click, wire:submit

wire:click associa un metodo all’evento click, wire:submit all’evento di invio del form.
<?php

use Livewire\Component;
use App\Models\Task;

new class extends Component {
    public string $taskName = '';

    public function addTask(): void
    {
        Task::create(['name' => $this->taskName]);
        $this->taskName = '';
    }

    public function render()
    {
        return $this->view([
            'tasks' => Task::latest()->get(),
        ]);
    }
};
?>

<div>
    <form wire:submit="addTask">
        <input type="text" wire:model="taskName" placeholder="Nome del task">
        <button type="submit">Aggiungi</button>
    </form>

    <ul>
        @foreach ($tasks as $task)
            <li>{{ $task->name }}</li>
        @endforeach
    </ul>
</div>

Validazione in tempo reale

In Livewire 4 puoi definire regole di validazione direttamente sulle proprietà con l’attributo #[Validate].
<?php

use Livewire\Attributes\Validate;
use Livewire\Component;
use App\Models\Post;

new class extends Component {
    #[Validate('required|min:3')]
    public string $title = '';

    #[Validate('required|min:10')]
    public string $content = '';

    public function save(): void
    {
        $this->validate();

        Post::create([
            'title' => $this->title,
            'content' => $this->content,
        ]);

        $this->reset(['title', 'content']);

        session()->flash('message', 'Articolo salvato.');
    }
};
?>

<div>
    @if (session('message'))
        <div>{{ session('message') }}</div>
    @endif

    <form wire:submit="save">
        <div>
            <input type="text" wire:model.live.blur="title" placeholder="Titolo">
            @error('title') <span style="color: red;">{{ $message }}</span> @enderror
        </div>

        <div>
            <textarea wire:model.live.blur="content" placeholder="Contenuto"></textarea>
            @error('content') <span style="color: red;">{{ $message }}</span> @enderror
        </div>

        <button type="submit">Salva</button>
    </form>
</div>
Le proprietà con #[Validate] vengono validate automaticamente a ogni aggiornamento. Combinandolo con wire:model.live.blur si ottiene un’esperienza di validazione in tempo reale in cui il messaggio d’errore compare appena si perde il focus.
$this->validate() valida tutte le proprietà insieme al momento dell’invio del form. Il pattern raccomandato è usarlo in combinazione con la validazione automatica di #[Validate] a due livelli.

Hook di ciclo di vita

Un componente Livewire ha diversi hook di ciclo di vita.
HookTiming
mount()Quando il componente viene creato per la prima volta (una sola volta)
boot()All’inizio di ogni richiesta (sia la prima che quelle successive)
updating($property, $value)Subito prima dell’aggiornamento della proprietà
updated($property)Subito dopo l’aggiornamento della proprietà
rendering()Prima del rendering della vista
rendered()Dopo il rendering della vista
dehydrate()Alla fine di ogni richiesta

mount() — inizializzazione

mount() si usa per inizializzare il componente. Sostituisce il costruttore.
<?php

use Illuminate\Support\Facades\Auth;
use Livewire\Component;

new class extends Component {
    public string $name = '';
    public string $email = '';

    public function mount(): void
    {
        $this->name = Auth::user()->name;
        $this->email = Auth::user()->email;
    }
};
?>

<div>
    <p>Nome: {{ $name }}</p>
    <p>Email: {{ $email }}</p>
</div>

updated() — elaborazione dopo la modifica di una proprietà

Se vuoi eseguire qualcosa dopo l’aggiornamento di una proprietà, usa updated(). Per restringere a una proprietà specifica, includila nel nome del metodo.
<?php

use Livewire\Component;

new class extends Component {
    public string $username = '';

    public function updatedUsername(): void
    {
        $this->username = strtolower($this->username);
    }
};
?>

<div>
    <input type="text" wire:model.live="username">
    <p>Nome utente: {{ $username }}</p>
</div>
A ogni input il valore viene automaticamente convertito in minuscolo.

Integrazione con Laravel

Uso dei modelli Eloquent

Livewire può contenere direttamente modelli Eloquent nelle proprietà.
<?php

use Livewire\Attributes\Validate;
use Livewire\Component;
use App\Models\User;

new class extends Component {
    public User $user;

    public function mount(User $user): void
    {
        $this->user = $user;
    }

    #[Validate('required|min:2')]
    public string $name = '';

    public function save(): void
    {
        $this->validate();
        $this->user->update(['name' => $this->name]);
        session()->flash('message', 'Profilo aggiornato.');
    }

    public function render()
    {
        return $this->view();
    }
};
?>

<div>
    @if (session('message'))
        <div>{{ session('message') }}</div>
    @endif

    <form wire:submit="save">
        <input type="text" wire:model="name" placeholder="Nome">
        @error('name') <span style="color: red;">{{ $message }}</span> @enderror
        <button type="submit">Aggiorna</button>
    </form>
</div>

Form object

Puoi mantenere semplici i componenti estraendo i form complessi in un form object.
php artisan livewire:form PostForm
namespace App\Livewire\Forms;

use Livewire\Attributes\Validate;
use Livewire\Form;
use App\Models\Post;

class PostForm extends Form
{
    #[Validate('required|min:3')]
    public string $title = '';

    #[Validate('required|min:10')]
    public string $content = '';

    public function store(): void
    {
        Post::create($this->only(['title', 'content']));
    }
}
Usa il form object dal componente.
<?php

use App\Livewire\Forms\PostForm;
use Livewire\Component;

new class extends Component {
    public PostForm $form;

    public function save(): void
    {
        $this->form->validate();
        $this->form->store();
        $this->form->reset();
        session()->flash('message', 'Post creato.');
    }
};
?>

<div>
    <form wire:submit="save">
        <input type="text" wire:model="form.title" placeholder="Titolo">
        @error('form.title') <span style="color: red;">{{ $message }}</span> @enderror

        <textarea wire:model="form.content" placeholder="Contenuto"></textarea>
        @error('form.content') <span style="color: red;">{{ $message }}</span> @enderror

        <button type="submit">Pubblica</button>
    </form>
</div>

Conclusioni

Ecco un riepilogo dei casi d’uso in cui Livewire eccelle.
Caso d’usoCosa realizzi con Livewire
Gestione dei formValidazione in tempo reale e visualizzazione degli errori
Elenchi di datiRicerca live, ordinamento, paginazione
Contatori e toggleAggiornamenti UI senza ricaricare la pagina
Pannelli di amministrazioneOperazioni CRUD collegate direttamente a Eloquent
Form a wizardGestione degli step implementata in PHP
Se sei un ingegnere Laravel con esperienza in Blade, con Livewire puoi iniziare da subito. Il suo punto di forza è realizzare UI interattive senza il costo di apprendimento di un framework JavaScript. Quando servono interazioni molto avanzate, in stile SPA, Inertia.js è più indicato, ma per usi come form, pannelli di amministrazione o tabelle dati Livewire spesso permette un’implementazione più semplice. Prova a partire da un piccolo componente.

Documentazione ufficiale di Livewire

Per tutte le funzionalità di Livewire (file upload, paginazione, testing, ecc.) consulta la documentazione ufficiale.
Ultima modifica il 13 luglio 2026