Un composant Blade Laravel vous permet de regrouper en un seul endroit les parties répétitives de votre interface et de les réutiliser sur chaque page. Plutôt que de copier-coller des structures comme des boutons, des cartes, des alertes ou des fenêtres modales, vous les définissez en tant que composants : vous transmettez les données via des props et gardez le contenu flexible grâce aux slots. Dans ce guide, je vous explique pas à pas comment construire des composants Blade à partir de zéro, la différence entre composants anonymes et basés sur une classe, le fonctionnement conjoint des props et des slots, et des astuces réellement utiles dans vos projets.
Qu'est-ce qu'un composant Blade et pourquoi l'utiliser ?
Blade est le moteur de templates de Laravel, et les composants en sont les éléments réutilisables et autonomes. Un composant comporte deux parties : la balise que vous utilisez de l'extérieur (par exemple <x-alert />) et le fichier Blade qui se trouve derrière. Les avantages sont clairs :
- Moins de répétition : vous ne réécrivez pas la même carte sur dix pages.
- Maintenance facilitée : quand le design change, vous modifiez un seul fichier.
- Meilleure lisibilité : le template de la page est composé de balises significatives.
- Testabilité : vous pouvez vérifier les composants isolément.
Créer votre premier composant
Le moyen le plus rapide de générer un composant est Artisan. La commande ci-dessous génère à la fois une classe et un fichier de vue :
php artisan make:component Alert
Cela crée deux fichiers : app/View/Components/Alert.php (la classe du composant) et resources/views/components/alert.blade.php (la vue). Pour utiliser le composant sur une page, écrivez sa balise avec le préfixe x- :
<x-alert />
La structure des dossiers se reflète à l'aide d'un séparateur. Par exemple, le fichier resources/views/components/forms/input.blade.php s'appelle <x-forms.input />.
Transmettre des données avec les props
Les composants reçoivent généralement des données de l'extérieur. Dans un composant basé sur une classe, cela se définit via les paramètres du constructeur. Dans l'exemple ci-dessous, type et message sont des props :
<?php
namespace App\View\Components;
use Illuminate\View\Component;
use Illuminate\View\View;
class Alert extends Component
{
public function __construct(
public string $type = 'info',
public string $message = '',
) {}
public function render(): View
{
return view('components.alert');
}
}
Dans le fichier de vue, vous accédez directement à ces propriétés :
<div class="alert alert-{{ $type }}">
{{ $message }}
</div>
À l'utilisation, vous transmettez les props comme des attributs HTML. Utilisez un attribut simple pour les valeurs statiques et le préfixe : pour les variables :
<x-alert type="danger" message="Enregistrement supprimé." />
<x-alert type="success" :message="$notice" />
Les noms d'attributs sont automatiquement convertis en camelCase : si vous écrivez card-title en HTML, vous le recevez sous la forme $cardTitle dans la classe.
Garder le contenu flexible avec les slots
Les props sont idéales pour les valeurs simples, mais quand vous voulez placer du HTML, d'autres composants ou un texte plus long à l'intérieur d'un composant, vous utilisez un slot. Tout ce qui se trouve entre les balises d'ouverture et de fermeture atterrit dans la variable {{ $slot }} de la vue :
<!-- components/card.blade.php -->
<div class="card">
<div class="card-body">
{{ $slot }}
</div>
</div>
<x-card>
<p>Ce texte est placé directement dans le slot.</p>
</x-card>
Slots nommés
La plupart des composants ont plusieurs zones de contenu : un en-tête, un corps, un pied de page. Pour cela, vous définissez des slots nommés. Dans la vue, vous marquez chaque zone avec sa propre variable :
<!-- components/card.blade.php -->
<div class="card">
<div class="card-header">{{ $title }}</div>
<div class="card-body">{{ $slot }}</div>
</div>
À l'utilisation, vous remplissez cette zone avec <x-slot:title> ; tout contenu non nommé va dans le $slot par défaut :
<x-card>
<x-slot:title>
Rapport mensuel
</x-slot>
<p>Le contenu principal va ici.</p>
</x-card>
Composants anonymes et attributs
Vous n'êtes pas obligé d'écrire une classe pour chaque composant. Pour des structures simples, uniquement constituées d'une vue, un composant anonyme suffit : vous créez simplement un fichier Blade sous resources/views/components/, sans classe. Vous déclarez les props en haut du fichier :
<!-- components/badge.blade.php -->
@props(['color' => 'gray'])
<span class="badge badge-{{ $color }}">
{{ $slot }}
</span>
Tous les attributs que vous n'avez pas déclarés sont rassemblés dans le sac $attributes. Vous pouvez les transmettre à l'élément racine, et même fusionner les classes intelligemment :
<span {{ $attributes->merge(['class' => 'badge']) }}>
{{ $slot }}
</span>
Ainsi, quand vous écrivez <x-badge class="ml-2" id="role">, la classe badge existante est conservée et les ml-2 et id entrants sont ajoutés. Cette approche rend les composants bien plus flexibles.
Bonnes habitudes en pratique
- Gardez anonymes les composants qui changent rarement et au contenu simple ; choisissez une classe quand vous avez besoin de logique (récupération de données, calcul).
- Donnez aux props des noms clairs et cohérents ; définissez des valeurs par défaut pour réduire les mauvaises utilisations.
- Laissez de la flexibilité avec
$attributes->merge(), mais gardez fixes les classes critiques. - Découpez les composants très volumineux ; chaque composant doit faire une seule chose, et bien.
Questions fréquentes
Dois-je utiliser un composant anonyme ou basé sur une classe ?
Si le contenu n'est qu'une vue et ne nécessite aucune logique PHP, un composant anonyme est plus simple et plus rapide. Si vous devez traiter des données, appeler un service ou faire des calculs, préférez un composant basé sur une classe.
Quelle est la différence entre props et slots ?
Les props servent à transmettre des valeurs simples (texte, nombres, booléens) depuis l'extérieur et s'écrivent comme des attributs. Un slot vous permet de placer du HTML ou d'autres composants à l'intérieur du composant ; il s'écrit entre les balises d'ouverture et de fermeture.
Pourquoi ma balise de composant ne fonctionne-t-elle pas ?
Les causes les plus fréquentes sont : le fichier qui n'est pas sous resources/views/components/, une incohérence de nommage, ou un cache de vue obsolète. Videz le cache avec php artisan view:clear et comparez le chemin du fichier avec la balise.
Vous voulez bâtir une couche d'interface propre et réutilisable dans votre projet ? Je développe des applications maintenables et évolutives avec Laravel et Blade. Pour discuter de votre idée, contactez-moi.