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

# ⚡ Einführung in Livewire 4 – Reaktive UIs ohne JavaScript

> Wie Sie mit dem offiziellen Laravel-Paket Livewire 4 interaktive UIs bauen, ohne JavaScript zu schreiben – von der Installation bis zu praxisnahen Codebeispielen.

## Was ist Livewire?

Wollte man in Laravel eine dynamische UI bauen, blieb früher nur die Kombination mit einem JavaScript-Framework wie Vue.js oder React – oder man schrieb selbst AJAX-Requests.

**Livewire** ist das Laravel-Paket, das dieses Problem löst. Reaktive UIs lassen sich allein mit PHP und Blade bauen. Funktionen wie Formular-Validierung in Echtzeit, Live-Suche oder Counter, die früher JavaScript benötigten, lassen sich vollständig in PHP umsetzen.

<Info>
  Livewire 4 läuft ab Laravel 10 und ab PHP 8.1. Die aktuelle Version ist Livewire 4.
</Info>

### Überblick über die Funktionsweise

Eine Livewire-Komponente ist eine Kombination aus einer serverseitigen PHP-Klasse und einem Blade-Template. Wenn der Nutzer auf einen Button klickt oder in ein Formular tippt, sendet Livewire im Hintergrund einen AJAX-Request, führt PHP aus und aktualisiert nur die geänderten Teile der Seite. Entwickler müssen sich um diesen Mechanismus nicht kümmern und schreiben ausschließlich PHP.

***

## Installation

Führen Sie im Root-Verzeichnis Ihrer Laravel-Anwendung folgenden Befehl aus:

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

Da Laravels Auto-Discovery aktiv ist, sind keine weiteren Einstellungen erforderlich.

### Layout-Datei erzeugen

Wenn Sie Livewire als Full-Page-Komponente verwenden, wird eine Layout-Datei benötigt. Diese generieren Sie mit folgendem Artisan-Kommando:

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

Es wird `resources/views/layouts/app.blade.php` erzeugt.

```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` und `@livewireScripts` laden die Assets von Livewire und Alpine.js automatisch.

***

## Die erste Komponente

Für das Erzeugen von Livewire-Komponenten gibt es ein eigenes Artisan-Kommando. Bauen wir einen einfachen Counter.

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

Dieses Kommando erzeugt eine Single-File-Komponente unter `resources/views/components/⚡counter.blade.php`.

<Tip>
  Das ⚡ im Dateinamen dient der raschen Erkennung von Livewire-Komponenten und verbessert die Übersichtlichkeit im Editor. Wenn Sie es nicht möchten, lässt es sich per Konfiguration deaktivieren.
</Tip>

Bearbeiten Sie die generierte Datei wie folgt:

```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>Zähler: {{ $count }}</h1>

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

Um diese Komponente in ein Blade-Template einzubetten, verwenden Sie die reguläre Blade-Component-Syntax:

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

Bei jedem Klick auf einen Button wird der Zähler ohne Seiten-Reload aktualisiert. `wire:click` ruft anstelle von JavaScript eine PHP-Methode auf.

***

## Properties und Actions

### Properties – `wire:model`

Mit der Direktive `wire:model` binden Sie ein Eingabe-Element bidirektional an eine Property der Komponente.

```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="Name">
    <input type="email" wire:model="email" placeholder="E-Mail">

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

Standardmäßig synchronisiert `wire:model` erst dann mit dem Server, wenn eine Action ausgeführt wird (etwa das Absenden des Formulars). Wenn Sie bei jeder Eingabe synchronisieren möchten, ergänzen Sie den Modifier `.live`.

| Schreibweise           | Verhalten                                                                         |
| ---------------------- | --------------------------------------------------------------------------------- |
| `wire:model`           | Synchronisation nur bei Ausführung einer Action (z. B. Formular-Submit) (Default) |
| `wire:model.live`      | Bei jeder Eingabe wird ein Request gesendet                                       |
| `wire:model.blur`      | Beim Verlassen des Fokus synchronisieren (kein Request)                           |
| `wire:model.live.blur` | Beim Verlassen des Fokus einen Request senden                                     |

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

`wire:click` bindet eine Methode an ein Click-Event, `wire:submit` an das Submit-Event eines Formulars.

```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="Aufgabenname">
        <button type="submit">Hinzufügen</button>
    </form>

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

***

## Echtzeit-Validierung

In Livewire 4 lassen sich Validierungsregeln direkt an Properties über das Attribut `#[Validate]` definieren.

```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', 'Beitrag wurde gespeichert.');
    }
};
?>

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

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

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

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

Bei Properties mit `#[Validate]` läuft bei jeder Änderung automatisch die Validierung. In Kombination mit `wire:model.live.blur` erhalten Sie eine Echtzeit-Validierung, bei der die Fehlermeldung genau im Moment des Fokusverlusts angezeigt wird.

<Info>
  `$this->validate()` prüft beim Absenden alle Properties gemeinsam. Die empfohlene Vorgehensweise ist die zweistufige Kombination mit der automatischen Validierung per `#[Validate]`.
</Info>

***

## Lifecycle-Hooks

Livewire-Komponenten kennen mehrere Lifecycle-Hooks.

| Hook                          | Zeitpunkt                                                      |
| ----------------------------- | -------------------------------------------------------------- |
| `mount()`                     | Wenn die Komponente erstmals erstellt wird (einmalig)          |
| `boot()`                      | Zu Beginn jedes Requests (sowohl initial als auch nachfolgend) |
| `updating($property, $value)` | Direkt vor dem Aktualisieren einer Property                    |
| `updated($property)`          | Direkt nach dem Aktualisieren einer Property                   |
| `rendering()`                 | Vor dem Rendern der View                                       |
| `rendered()`                  | Nach dem Rendern der View                                      |
| `dehydrate()`                 | Am Ende jedes Requests                                         |

### `mount()` – Initialisierung

`mount()` wird für die Initialisierung der Komponente genutzt. Es ersetzt den Konstruktor.

```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>Name: {{ $name }}</p>
    <p>E-Mail: {{ $email }}</p>
</div>
```

### `updated()` – Verarbeitung nach der Property-Änderung

Wenn Sie nach der Aktualisierung einer Property eingreifen möchten, verwenden Sie `updated()`. Um eine bestimmte Property zu adressieren, hängen Sie deren Namen an den Methodennamen an.

```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>Benutzername: {{ $username }}</p>
</div>
```

Bei jeder Eingabe wird automatisch in Kleinbuchstaben umgewandelt.

***

## Integration mit Laravel

### Nutzung von Eloquent-Modellen

Livewire kann Eloquent-Modelle direkt als Property halten.

```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 wurde aktualisiert.');
    }

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

### Form-Objekte

Komplexe Formulare können in Form-Objekte ausgelagert werden, damit Komponenten schlank bleiben.

```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']));
    }
}
```

Verwenden Sie das Form-Objekt in einer Komponente:

```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', 'Beitrag wurde erstellt.');
    }
};
?>

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

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

        <button type="submit">Veröffentlichen</button>
    </form>
</div>
```

***

## Fazit

Anwendungsfälle, für die Livewire besonders geeignet ist:

| Anwendungsfall       | Was Livewire ermöglicht                          |
| -------------------- | ------------------------------------------------ |
| Formularverarbeitung | Echtzeit-Validierung, Fehlerdarstellung          |
| Datenlisten          | Live-Suche, Sortierung, Pagination               |
| Counter und Toggles  | UI-Aktualisierung ohne Seiten-Reload             |
| Admin-Panels         | CRUD-Operationen mit direkter Eloquent-Anbindung |
| Wizard-Formulare     | Schrittsteuerung in PHP                          |

Livewire ist für Laravel-Entwickler, die Blade bereits einmal verwendet haben, sofort einsatzbereit. Der größte Vorteil ist, dass sich interaktive UIs ohne die Lernkurve eines JavaScript-Frameworks umsetzen lassen.

Für Szenarien mit SPA-nahen, hochkomplexen Interaktionen eignet sich Inertia.js besser; für Formulare, Admin-Panels oder Data Tables ist Livewire jedoch häufig einfacher umzusetzen. Beginnen Sie am besten mit einer kleinen Komponente.

<Card title="Offizielle Livewire-Dokumentation" icon="book-open" href="https://livewire.laravel.com/docs">
  Alle Funktionen (Datei-Uploads, Pagination, Testen usw.) finden Sie in der offiziellen Dokumentation.
</Card>


## Related topics

- [Einführung in die Authentifizierung](/de/authentication.md)
- [Frontend](/de/frontend.md)
- [Starter Kits](/de/starter-kits.md)
- [SPAs mit Inertia.js entwickeln](/de/blog/inertia-introduction.md)
- [Laravel Pulse](/de/pulse.md)
