Aller au contenu principal

Module 1 – Introduction à Livewire

Niveau 5.1 – Laravel Livewire


Ce module introduit Livewire : son rôle dans l’écosystème Laravel (Blade, Inertia, SPA), le cycle requête/réponse sans JavaScript dédié, et la création du premier composant. La fin du module aborde les sujets avancés (composants paramétrés, optimisation, intégration Alpine).


Objectif

À la fin de ce module, vous saurez :

  • Ce qu’est Laravel Livewire et en quoi il diffère d’une SPA JavaScript, d’Inertia ou d’un site Laravel classique (Blade seul).
  • Quand choisir Livewire : back-offices, tableaux de bord, formulaires dynamiques sans écrire d’API ni de JavaScript métier.
  • Comment un composant Livewire fonctionne : logique en PHP, rendu en Blade, interactions via AJAX et mise à jour du DOM (morphing).
  • Installer Livewire dans un projet Laravel et créer votre premier composant (compteur) de bout en bout.

Ce module pose les bases conceptuelles ; les modules suivants détaillent le data binding, les formulaires, Eloquent, les tests, etc.

En une phrase : Livewire vous permet d’avoir des interfaces réactives (filtres, formulaires dynamiques, listes qui se mettent à jour sans rechargement) en restant 100 % en PHP et Blade, sans écrire d’API ni de JavaScript métier.


Le problème que Livewire résout

Contexte (débutant)

En développement web avec Laravel, on a souvent :

  1. Pages Blade classiques : chaque clic sur un lien ou soumission de formulaire = nouvelle requête = toute la page se recharge. C’est simple et robuste, mais dès qu’on veut des filtres en temps réel, un tableau qui se met à jour sans rechargement, ou un formulaire avec validation au fil de l’eau, on est tenté d’ajouter du JavaScript (AJAX, fetch, manipulation du DOM). On se retrouve à maintenir à la fois du PHP (serveur) et du JS (client), avec des risques de duplication (validation, logique métier).

  2. SPA (React, Vue, etc.) : l’interface est gérée entièrement en JavaScript ; le serveur expose une API. Expérience très fluide, mais vous devez construire et maintenir une API, l’auth (tokens), le routing côté client, etc. Souvent disproportionné pour un back-office ou un tableau de bord interne.

Livewire se place entre les deux : vous restez 100 % dans Laravel (PHP + Blade). La logique (validation, requêtes BDD, règles métier) reste dans des composants PHP ; la vue est du Blade classique. En revanche, les interactions (clic, saisie, soumission) ne provoquent pas de rechargement complet : Livewire envoie l’état du composant au serveur en AJAX, le serveur exécute la méthode concernée, renvoie le nouveau HTML, et le client met à jour le DOM (souvent via du morphing). Résultat : une interface réactive (filtres, formulaires dynamiques, listes paginées) sans écrire d’API ni de JavaScript métier.

Pour aller plus loin (expert)

  • Livewire sérialise l’état du composant (toutes les propriétés publiques) et l’envoie avec chaque requête AJAX (dans le payload). Le serveur désérialise cet état, réhydrate l’instance du composant, exécute la méthode demandée (ex. increment()), puis appelle render(). Le HTML produit est renvoyé au client. Côté navigateur, Livewire compare ce HTML au DOM actuel (algorithme de morphing, type morphdom) et n’applique que les différences : d’où l’absence de flash blanc et la préservation du scroll, du focus et des états des inputs.
  • Taille du payload : plus vous avez de propriétés publiques (surtout des tableaux ou objets volumineux), plus la requête et la réponse sont lourdes. Pour des listes longues, ne stockez pas la collection entière dans une propriété ; gardez les filtres (search, page) et recalculez la liste dans render() (voir module 6).
  • Vous pouvez combiner Livewire avec du JavaScript : wire:ignore pour exclure un bloc du morphing (ex. une librairie JS qui gère son propre DOM), Alpine.js (inclus avec Livewire 3) pour des interactions purement client (dropdown, tooltip) sans round-trip serveur.

Qu’est-ce que Livewire, concrètement ?

Livewire est un package Laravel (côté serveur + un petit script côté client) qui permet de définir des composants constitués de :

  1. Une classe PHP (sous App\Livewire par défaut) : propriétés publiques (état du composant) et méthodes (actions : clic, soumission, etc.). Ces méthodes s’exécutent côté serveur.
  2. Une vue Blade (sous resources/views/livewire/) : le template HTML qui affiche les propriétés et déclenche les actions via des directives Livewire (wire:click, wire:model, wire:submit, etc.).

Quand l’utilisateur agit (clic sur un bouton, saisie dans un champ), le navigateur envoie une requête AJAX à Laravel avec l’identifiant du composant et l’état courant. Laravel réinstancie le composant, met à jour les propriétés si besoin (ex. wire:model), appelle la méthode demandée (ex. increment()), puis re-rend la vue Blade. La réponse (nouveau HTML ou diff) est renvoyée au client ; Livewire met à jour le DOM. Tout cela sans rechargement complet de la page.

Idée clé : Backend-driven UI

  • Toute la logique (calculs, validation, Eloquent, règles métier) s’exécute côté serveur (PHP).
  • Le navigateur n’a pas besoin de connaître les règles de validation ni la structure de la BDD : il envoie les données, le serveur répond avec du HTML à jour.

Livewire vs Vue/React (SPA) vs Inertia

Pour bien situer Livewire, voici trois façons de construire une interface « réactive » avec Laravel.

StackOù s’exécute la logique ?RenduCas d’usage typique
Vue / React (SPA)Côté client (JavaScript)Composants JSApps très interactives, routing client, équipe front lourde
Inertia.jsLaravel (routes, contrôleurs)Composants Vue/ReactPages modernes (UI React/Vue) sans API dédiée, une seule codebase
LivewireLaravel (PHP dans des composants)Blade (HTML)Back-offices, tableaux de bord, formulaires dynamiques, tout en PHP/Blade
  • Livewire : idéal quand vous voulez réactivité (filtres, pagination, formulaires avec feedback immédiat) sans écrire de JavaScript métier ni maintenir une API. Toute l’équipe peut rester sur PHP et Blade.
  • Inertia : idéal si vous voulez React ou Vue (composants, écosystème npm) tout en gardant Laravel pour le routing et les données, sans construire une API REST.
  • SPA classique : quand vous avez besoin d’une API pour plusieurs clients (web, mobile) ou des équipes front/back très séparées.

Cycle de vie d’un composant

Pour bien comprendre « qui fait quoi », voici le parcours d’une interaction.

  1. Chargement initial : l’utilisateur ouvre une page qui contient un composant Livewire (ex. <livewire:counter />). Laravel rend la page ; le premier rendu du composant s’exécute (mount() si défini, puis render()). Le HTML est envoyé au navigateur ; Livewire hydrate le composant côté client (attache les écouteurs, enregistre l’état).
  2. Action utilisateur : l’utilisateur clique sur « +1 » (wire:click="increment"). Le script Livewire envoie une requête AJAX vers Laravel avec : le nom du composant, son ID, l’état actuel des propriétés, et l’action à exécuter (increment).
  3. Côté serveur : Laravel réinstancie le composant, restaure les propriétés (ex. $count = 0), appelle increment(). La méthode modifie $this->count++. Puis render() est appelé ; la vue Blade est rendue avec la nouvelle valeur.
  4. Retour au client : Livewire reçoit le nouveau HTML (ou un diff). Il met à jour le DOM (morphing) : seul le texte « Compteur : 1 » change, pas de rechargement complet. L’utilisateur garde le scroll, le focus, etc.

Installation (Livewire 3)

Dans un projet Laravel existant :

composer require livewire/livewire

Aucune configuration obligatoire : Livewire 3 utilise les découvertes automatiques. En revanche, votre layout Blade principal doit inclure les styles et scripts Livewire pour que les composants fonctionnent.

Layout type (resources/views/layouts/app.blade.php) :

<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{{ $title ?? 'Mon app' }}</title>
@livewireStyles
</head>
<body>
{{ $slot ?? '' }}
@livewireScripts
</body>
</html>
  • @livewireStyles : injecte les styles nécessaires (indicateurs de chargement, etc.).
  • @livewireScripts : injecte le script JavaScript qui gère les requêtes AJAX et la mise à jour du DOM. À placer avant la fermeture de </body>.

Si vous utilisez Alpine.js (fourni avec Livewire 3), il est déjà inclus via @livewireScripts. Vous pouvez l’utiliser pour des interactions purement visuelles (dropdown, tooltip) sans appeler le serveur.


Premier composant : un compteur

Nous allons créer un composant Counter : un nombre et un bouton « +1 ». Chaque clic appelle une méthode PHP qui incrémente le compteur ; la vue se met à jour sans rechargement.

Créer le composant

php artisan make:livewire Counter

Cela crée deux fichiers :

  • Classe : app/Livewire/Counter.php
  • Vue : resources/views/livewire/counter.blade.php

La classe PHP

<?php

namespace App\Livewire;

use Livewire\Component;

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

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

public function render()
{
return view('livewire.counter');
}
}
  • $count : propriété publique. Elle fait partie de l’état du composant ; Livewire la sérialise et la renvoie au client, puis la réhydrate à chaque requête. La vue Blade peut l’afficher.
  • increment() : méthode publique. Elle est appelée côté serveur quand l’utilisateur clique sur l’élément qui a wire:click="increment". Après l’exécution, Livewire appelle render() et renvoie le nouveau HTML.
  • render() : retourne la vue Blade du composant. Elle est exécutée après mount() (premier chargement) et après chaque action (ex. après increment()).

La vue Blade

<div>
<h1>Compteur : {{ $count }}</h1>
<button wire:click="increment">+1</button>
</div>
  • {{ $count }} : affiche la propriété publique $count du composant.
  • wire:click="increment" : au clic, Livewire envoie une requête au serveur pour appeler la méthode increment() du composant, puis met à jour le DOM avec le nouveau rendu.

Afficher le composant dans une page

Dans n’importe quelle vue Blade (page d’accueil, layout, etc.) :

<livewire:counter />

Ou avec la directive :

@livewire('counter')

Les deux syntaxes sont équivalentes. Après rechargement de la page, vous devez voir « Compteur : 0 » et un bouton « +1 ». En cliquant, le nombre s’incrémente sans rechargement de la page : c’est Livewire qui envoie l’action au serveur et met à jour uniquement le bloc du composant.


À retenir

  • Livewire = interfaces réactives en PHP + Blade. Logique côté serveur (propriétés publiques + méthodes), rendu Blade ; les interactions passent par AJAX et mise à jour du DOM (morphing).
  • Backend-driven : pas d’API à écrire, pas de JavaScript métier à maintenir. Idéal pour back-offices, tableaux de bord, formulaires dynamiques.
  • Installation : composer require livewire/livewire puis @livewireStyles et @livewireScripts dans le layout.
  • Premier composant : php artisan make:livewire NomDuComposant crée la classe (état + méthodes) et la vue Blade. Afficher avec <livewire:nom-du-composant /> ou @livewire('nom-du-composant').
  • wire:click="nomMethode" appelle la méthode côté serveur ; render() est relancé et le DOM est mis à jour.

Comparaison rapide : en Blade classique, un compteur « +1 » demanderait un formulaire ou un lien qui recharge toute la page. En Livewire, un seul wire:click="increment" : la requête part en AJAX, le serveur incrémente $count et renvoie le nouveau HTML du composant ; seul le bloc du compteur est mis à jour. Vous gardez la simplicité PHP/Blade avec une UX « SPA-like ».


En résumé : qui fait quoi ?

Où ?Qui fait quoi ?
NavigateurAffiche le HTML rendu par Laravel. Envoie des requêtes AJAX (état du composant + action) au clic / saisie. Reçoit le nouveau HTML (ou diff) et met à jour le DOM (morphing). N’exécute pas la logique métier.
Laravel (serveur)Reçoit la requête Livewire. Réhydrate le composant (propriétés), exécute la méthode appelée (ex. increment()), appelle render(), renvoie le HTML (ou le diff). Toute la logique (calculs, BDD, validation) est ici.
Classe PHPÉtat = propriétés publiques. Actions = méthodes publiques appelées par wire:click / wire:submit. render() retourne la vue Blade.
Vue BladeAffiche les propriétés ({{ $count }}). Déclenche les actions (wire:click="increment", wire:model="query").

Checklist débutant

Avant de passer au module 2, vérifiez que vous savez :

  • Expliquer en une phrase ce que fait Livewire (interfaces réactives en PHP/Blade, sans API ni JS métier).
  • Installer Livewire (composer require livewire/livewire) et ajouter @livewireStyles et @livewireScripts dans le layout.
  • Créer un composant avec php artisan make:livewire NomDuComposant et connaître les deux fichiers générés (classe + vue).
  • Dans la classe : déclarer une propriété publique (ex. $count), une méthode publique (ex. increment()), et render() qui retourne la vue.
  • Dans la vue : afficher la propriété avec {{ $count }} et appeler la méthode avec wire:click="increment". Inclure le composant dans une page avec <livewire:counter /> ou @livewire('counter').

Approfondissement

  • Passer des paramètres au composant : dans la vue qui inclut le composant, vous pouvez passer des données : <livewire:post-detail :post-id="$post->id" />. Dans la classe, récupérez-les dans mount() : public function mount(int $postId): void { $this->post = Post::findOrFail($postId); }. Les paramètres de mount() ne sont pas automatiquement des propriétés publiques ; assignez-les à des propriétés si vous devez les garder entre les requêtes.
  • Plusieurs composants sur la même page : chaque instance a son propre état et son propre ID Livewire. Vous pouvez avoir trois <livewire:counter /> sur une page : chacun garde son $count indépendant.
  • Namespace et dossier personnalisés : par défaut les classes sont dans App\Livewire et les vues dans resources/views/livewire/ avec le nom en kebab-case. Vous pouvez déplacer les classes (ex. App\Livewire\Dashboard\Stats) et adapter le nom du composant pour l’affichage (<livewire:dashboard.stats />). La convention reste : nom de classe → kebab-case pour la balise.
  • Performance : pour des composants très interactifs (liste avec des dizaines de champs en wire:model), pensez à wire:model.defer ou .lazy pour réduire le nombre de requêtes. Nous détaillons cela au module 3.

À retenir

  • Livewire = interfaces réactives en PHP + Blade. Logique côté serveur (propriétés publiques + méthodes), rendu Blade ; les interactions passent par AJAX et mise à jour du DOM (morphing).
  • Backend-driven : pas d’API à écrire, pas de JavaScript métier à maintenir. Idéal pour back-offices, tableaux de bord, formulaires dynamiques.
  • Installation : composer require livewire/livewire puis @livewireStyles et @livewireScripts dans le layout.
  • Premier composant : php artisan make:livewire NomDuComposant crée la classe (état + méthodes) et la vue Blade. Afficher avec <livewire:nom-du-composant /> ou @livewire('nom-du-composant').
  • wire:click="nomMethode" appelle la méthode côté serveur ; render() est relancé et le DOM est mis à jour. mount() pour l’initialisation (paramètres, chargement de données) ; détaillé au module 7.

Dans le prochain module, nous détaillons la structure des composants : propriétés publiques, wire:model (liaison bidirectionnelle), wire:submit, et le flux render / cycle de vie.