Mit einer Laravel Blade Component kannst du die sich wiederholenden Teile deiner Oberfläche an einer Stelle bündeln und auf jeder Seite wiederverwenden. Anstatt Strukturen wie Buttons, Karten, Hinweise oder Modals per Copy-and-paste zu vervielfältigen, definierst du sie als Komponenten: Daten übergibst du über Props und hältst den Inhalt mit Slots flexibel. In diesem Leitfaden zeige ich dir Schritt für Schritt, wie du Blade-Komponenten von Grund auf erstellst, worin sich anonyme und klassenbasierte Komponenten unterscheiden, wie Props und Slots zusammenarbeiten und welche Tipps in echten Projekten wirklich nützlich sind.
Was ist eine Blade-Komponente und warum nutzt man sie?
Blade ist die Template-Engine von Laravel, und Komponenten sind ihre wiederverwendbaren, in sich geschlossenen Bausteine. Eine Komponente besteht aus zwei Teilen: dem Tag, das du von außen verwendest (zum Beispiel <x-alert />), und der dahinterliegenden Blade-Datei. Die Vorteile liegen auf der Hand:
- Weniger Wiederholung: Du schreibst dieselbe Karte nicht auf zehn Seiten neu.
- Einfachere Wartung: Ändert sich das Design, bearbeitest du eine einzige Datei.
- Bessere Lesbarkeit: Das Seitentemplate besteht aus aussagekräftigen Tags.
- Testbarkeit: Du kannst Komponenten isoliert überprüfen.
Deine erste Komponente erstellen
Der schnellste Weg, eine Komponente anzulegen, ist Artisan. Der folgende Befehl erzeugt sowohl eine Klasse als auch eine View-Datei:
php artisan make:component Alert
Dies erstellt zwei Dateien: app/View/Components/Alert.php (die Komponentenklasse) und resources/views/components/alert.blade.php (die View). Um die Komponente auf einer Seite zu nutzen, schreibst du ihr Tag mit dem Präfix x-:
<x-alert />
Die Ordnerstruktur wird über ein Trennzeichen abgebildet. Die Datei resources/views/components/forms/input.blade.php rufst du beispielsweise als <x-forms.input /> auf.
Daten mit Props übergeben
Komponenten erhalten meist Daten von außen. In einer klassenbasierten Komponente definierst du das über die Parameter des Konstruktors. Im folgenden Beispiel sind type und message 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');
}
}
In der View-Datei greifst du direkt auf diese Eigenschaften zu:
<div class="alert alert-{{ $type }}">
{{ $message }}
</div>
Bei der Verwendung übergibst du die Props wie HTML-Attribute. Für statische Werte nutzt du ein normales Attribut, für Variablen das Präfix ::
<x-alert type="danger" message="Datensatz gelöscht." />
<x-alert type="success" :message="$notice" />
Attributnamen werden automatisch in camelCase umgewandelt: Schreibst du card-title im HTML, erhältst du es in der Klasse als $cardTitle.
Inhalt mit Slots flexibel halten
Props eignen sich ideal für einfache Werte; willst du jedoch HTML, andere Komponenten oder längeren Text in eine Komponente legen, verwendest du einen Slot. Alles zwischen dem öffnenden und schließenden Tag landet in der Variable {{ $slot }} in der View:
<!-- components/card.blade.php -->
<div class="card">
<div class="card-body">
{{ $slot }}
</div>
</div>
<x-card>
<p>Dieser Text wird direkt in den Slot eingefügt.</p>
</x-card>
Benannte Slots
Die meisten Komponenten haben mehr als einen Inhaltsbereich: einen Kopf, einen Körper, einen Fuß. Dafür definierst du benannte Slots. In der View kennzeichnest du jeden Bereich mit einer eigenen Variable:
<!-- components/card.blade.php -->
<div class="card">
<div class="card-header">{{ $title }}</div>
<div class="card-body">{{ $slot }}</div>
</div>
Bei der Verwendung füllst du diesen Bereich mit <x-slot:title>; jeder unbenannte Inhalt geht in den Standard-$slot:
<x-card>
<x-slot:title>
Monatsbericht
</x-slot>
<p>Der Hauptinhalt kommt hierher.</p>
</x-card>
Anonyme Komponenten und Attributes
Du musst nicht für jede Komponente eine Klasse schreiben. Für einfache, reine View-Strukturen genügt eine anonyme Komponente: Du legst einfach eine Blade-Datei unter resources/views/components/ an, ohne Klasse. Die Props deklarierst du am Anfang der Datei:
<!-- components/badge.blade.php -->
@props(['color' => 'gray'])
<span class="badge badge-{{ $color }}">
{{ $slot }}
</span>
Jedes Attribut, das du nicht deklariert hast, wird im $attributes-Bag gesammelt. Du kannst diese an das Wurzelelement weiterreichen und sogar Klassen intelligent zusammenführen:
<span {{ $attributes->merge(['class' => 'badge']) }}>
{{ $slot }}
</span>
Schreibst du also <x-badge class="ml-2" id="role">, bleibt die vorhandene badge-Klasse erhalten und die hinzukommenden ml-2 und id werden ergänzt. Dieser Ansatz macht Komponenten deutlich flexibler.
Gute Gewohnheiten in der Praxis
- Halte Komponenten, die sich selten ändern und einfachen Inhalt haben, anonym; wähle klassenbasiert, wenn du Logik brauchst (Daten laden, Berechnungen).
- Gib Props klare, konsistente Namen; definiere Standardwerte, um Fehlanwendungen zu verringern.
- Lass mit
$attributes->merge()Spielraum für Flexibilität, halte aber kritische Klassen fest. - Zerlege sehr große Komponenten; jede Komponente sollte eine Aufgabe gut erledigen.
Häufige Fragen
Soll ich eine anonyme oder eine klassenbasierte Komponente verwenden?
Ist der Inhalt rein eine View und braucht keine PHP-Logik, ist eine anonyme Komponente einfacher und schneller. Musst du Daten verarbeiten, einen Service aufrufen oder Berechnungen durchführen, bevorzuge eine klassenbasierte Komponente.
Was ist der Unterschied zwischen Props und Slots?
Props dienen dazu, einfache Werte (Text, Zahlen, Booleans) von außen zu übergeben, und werden als Attribute geschrieben. Ein Slot erlaubt es dir, HTML oder andere Komponenten in die Komponente zu legen; er steht zwischen dem öffnenden und schließenden Tag.
Warum funktioniert mein Komponenten-Tag nicht?
Die häufigsten Ursachen sind: Die Datei liegt nicht unter resources/views/components/, eine Namensabweichung oder ein veralteter View-Cache. Leere den Cache mit php artisan view:clear und vergleiche den Dateipfad mit dem Tag.
Möchtest du in deinem Projekt eine saubere, wiederverwendbare UI-Schicht aufbauen? Ich entwickle wartbare, skalierbare Anwendungen mit Laravel und Blade. Um deine Idee zu besprechen, nimm Kontakt mit mir auf.