> ## Documentation Index
> Fetch the complete documentation index at: https://kawax.biz/llms.txt
> Use this file to discover all available pages before exploring further.

# ⚡Introduction à Livewire 4 — créer des UI réactives sans JavaScript

> Comment construire une UI interactive sans écrire de JavaScript grâce à Livewire 4, package Laravel de première partie. De l'installation aux exemples concrets.

## Qu'est-ce que Livewire ?

Pour construire une UI dynamique avec Laravel, il fallait auparavant combiner un framework JavaScript comme Vue.js ou React, ou écrire soi-même les requêtes AJAX.

**Livewire** est le package Laravel qui résout ce problème. Il vous permet de construire des UI réactives uniquement en PHP et Blade. Validation de formulaires en temps réel, recherche en direct, compteurs — tout ce qui nécessitait autrefois du JavaScript se fait désormais en PHP.

<Info>
  Livewire 4 fonctionne avec Laravel 10 ou supérieur et PHP 8.1 ou supérieur. La dernière version en date est Livewire 4.
</Info>

### Vue d'ensemble

Un composant Livewire associe une classe PHP côté serveur et un template Blade. Quand l'utilisateur clique sur un bouton ou saisit dans un champ, Livewire envoie en coulisses une requête AJAX, exécute le code PHP, puis met à jour uniquement les parties modifiées de la page. Le développeur n'a pas à se soucier de ce mécanisme : tout s'écrit en PHP.

***

## Installation

Exécutez la commande suivante à la racine de votre application Laravel.

```shell theme={null}
composer require livewire/livewire
```

Grâce à la détection automatique des packages Laravel, aucune configuration supplémentaire n'est requise.

### Créer le fichier de layout

Pour utiliser un composant en tant que page complète, il faut un fichier de layout. Générez-le avec la commande Artisan suivante.

```shell theme={null}
php artisan livewire:layout
```

Le fichier `resources/views/layouts/app.blade.php` est créé.

```blade theme={null}
<!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` et `@livewireScripts` chargent automatiquement les assets de Livewire et Alpine.js.

***

## Premier composant

Une commande Artisan permet de générer un composant Livewire. Créons un compteur simple.

```shell theme={null}
php artisan make:livewire Counter
```

Cette commande génère un composant à fichier unique : `resources/views/components/⚡counter.blade.php`.

<Tip>
  Le ⚡ dans le nom de fichier permet d'identifier immédiatement un composant Livewire. Cela améliore la visibilité dans l'éditeur. Vous pouvez le désactiver dans la configuration si vous préférez.
</Tip>

Éditez le fichier généré comme suit.

```blade theme={null}
<?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>Compteur : {{ $count }}</h1>

    <button wire:click="increment">+1</button>
    <button wire:click="decrement">-1</button>
</div>
```

Pour intégrer ce composant dans un template Blade, utilisez la syntaxe classique des composants Blade.

```blade theme={null}
<livewire:counter />
```

À chaque clic, le compteur se met à jour sans rechargement de page. `wire:click` appelle une méthode PHP à la place du JavaScript.

***

## Propriétés et actions

### Propriétés — `wire:model`

La directive `wire:model` réalise un binding bidirectionnel entre un champ et une propriété du composant.

```blade theme={null}
<?php

use Livewire\Component;

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

<div>
    <input type="text" wire:model="name" placeholder="Nom">
    <input type="email" wire:model="email" placeholder="E-mail">

    <p>Bonjour {{ $name }} ({{ $email }})</p>
</div>
```

Par défaut, `wire:model` se synchronise avec le serveur uniquement quand une action est déclenchée (envoi de formulaire par exemple). Pour synchroniser à chaque saisie, ajoutez le modificateur `.live`.

| Écriture               | Comportement                                                                    |
| ---------------------- | ------------------------------------------------------------------------------- |
| `wire:model`           | Synchronise à l'exécution d'une action (envoi de formulaire, etc.) — par défaut |
| `wire:model.live`      | Envoie une requête à chaque saisie                                              |
| `wire:model.blur`      | Synchronise à la perte de focus (sans requête)                                  |
| `wire:model.live.blur` | Envoie une requête à la perte de focus                                          |

### Actions — `wire:click`, `wire:submit`

`wire:click` associe une méthode à un événement de clic, `wire:submit` à un événement d'envoi de formulaire.

```blade theme={null}
<?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="Nom de la tâche">
        <button type="submit">Ajouter</button>
    </form>

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

***

## Validation en temps réel

Livewire 4 permet de définir directement les règles de validation sur les propriétés via l'attribut `#[Validate]`.

```blade theme={null}
<?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', 'Article enregistré.');
    }
};
?>

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

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

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

        <button type="submit">Enregistrer</button>
    </form>
</div>
```

Les propriétés annotées avec `#[Validate]` sont validées automatiquement à chaque mise à jour. Combiné avec `wire:model.live.blur`, cela procure une validation en temps réel où le message d'erreur apparaît dès la perte de focus.

<Info>
  `$this->validate()` valide toutes les propriétés en même temps lors de l'envoi. Le patron recommandé est d'utiliser en deux temps la validation automatique via `#[Validate]` et cet appel.
</Info>

***

## Hooks de cycle de vie

Un composant Livewire dispose de plusieurs hooks de cycle de vie.

| Hook                          | Moment                                          |
| ----------------------------- | ----------------------------------------------- |
| `mount()`                     | Création initiale du composant (une seule fois) |
| `boot()`                      | Début de chaque requête (initiale et suivantes) |
| `updating($property, $value)` | Juste avant la mise à jour d'une propriété      |
| `updated($property)`          | Juste après la mise à jour d'une propriété      |
| `rendering()`                 | Avant le rendu de la vue                        |
| `rendered()`                  | Après le rendu de la vue                        |
| `dehydrate()`                 | Fin de chaque requête                           |

### `mount()` — initialisation

`mount()` s'utilise pour initialiser le composant. Il remplace le constructeur.

```blade theme={null}
<?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>Nom : {{ $name }}</p>
    <p>E-mail : {{ $email }}</p>
</div>
```

### `updated()` — traitement après changement de propriété

Pour agir après le changement d'une propriété, utilisez `updated()`. Ciblez une propriété spécifique en incluant son nom dans le nom de la méthode.

```blade theme={null}
<?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>Nom d'utilisateur : {{ $username }}</p>
</div>
```

Chaque saisie est automatiquement convertie en minuscules.

***

## Intégration avec Laravel

### Utilisation des modèles Eloquent

Livewire peut conserver directement un modèle Eloquent en propriété.

```blade theme={null}
<?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', 'Profil mis à jour.');
    }

    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="Nom">
        @error('name') <span style="color: red;">{{ $message }}</span> @enderror
        <button type="submit">Mettre à jour</button>
    </form>
</div>
```

### Objets Form

Pour un formulaire complexe, il est utile d'extraire la logique dans un objet Form afin de garder le composant simple.

```shell theme={null}
php artisan livewire:form PostForm
```

```php theme={null}
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']));
    }
}
```

Utilisation de cet objet Form depuis un composant.

```blade theme={null}
<?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', 'Article créé.');
    }
};
?>

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

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

        <button type="submit">Publier</button>
    </form>
</div>
```

***

## Conclusion

Récapitulatif des cas d'usage où Livewire brille particulièrement.

| Cas d'usage                 | Ce que Livewire permet                          |
| --------------------------- | ----------------------------------------------- |
| Traitement de formulaire    | Validation en temps réel, affichage des erreurs |
| Liste de données            | Recherche live, tri, pagination                 |
| Compteurs et toggles        | Mises à jour UI sans rechargement               |
| Interfaces d'administration | Opérations CRUD directement liées à Eloquent    |
| Formulaires en assistant    | Gestion des étapes en PHP                       |

Livewire est immédiatement accessible à tout ingénieur Laravel qui connaît Blade. Son plus grand atout est de permettre des UI interactives sans le coût d'apprentissage d'un framework JavaScript.

Pour une interactivité poussée façon SPA, Inertia.js est mieux adapté ; mais pour des formulaires, un back-office ou un tableau de données, Livewire est souvent plus simple. Commencez par un petit composant pour vous faire une idée.

<Card title="Documentation officielle Livewire" icon="book-open" href="https://livewire.laravel.com/docs">
  Consultez la documentation officielle pour toutes les fonctionnalités (upload de fichiers, pagination, tests, etc.).
</Card>


## Related topics

- [Introduction à l'authentification](/fr/authentication.md)
- [Frontend](/fr/frontend.md)
- [Introduction à React — bases pour l'utiliser avec Inertia × Laravel](/fr/blog/react-introduction.md)
- [Construire une SPA avec Inertia.js](/fr/blog/inertia-introduction.md)
- [Introduction à Svelte — bases pour l'utiliser avec Inertia × Laravel](/fr/blog/svelte-introduction.md)
