Preskočiť na obsah
Backend Laravel 17. apríl 2026 · 11 min čítania

Livewire 3 — fullstack Laravel bez JavaScriptu

Livewire 3 prináša reaktívne UI komponenty priamo do Blade šablón — bez potreby písať API endpointy, bez NPM závislostí na frontende, bez prepínania kontextu medzi PHP a JavaScriptom. Pre väčšinu Laravel projektov je to rýchlejší a lacnejší spôsob ako dosiahnuť dynamické UI ako Inertia.js + Vue.

DC

Dušan Chlpek

Senior PHP vývojár · GEAR s.r.o. · 25+ rokov praxe

Livewire vs. Inertia.js vs. klasické SPA — kedy čo?

Pred tým, než začneme s kódom, treba pochopiť, kde Livewire dáva zmysel a kde nie. Toto rozhodnutie ovplyvní celú architektúru projektu.

KritériumLivewire 3Inertia.js + Vue/ReactSPA (API + frontend)
TímPHP vývojáriPHP + JS vývojáriSeparátne tímy
Rýchlosť vývojaVysokáStrednáNízka
SEOVýborne (SSR)Dobre (SSR možné)Komplikované
Real-time (WebSocket)Cez Reverb/EchoCez EchoNatívne
Offline podporaNieObmedzeneÁno (PWA)
Veľké SPA aplikácieNevhodnéVhodnéIdeálne

Livewire 3 je ideálny pre: CRUD administrácie, rezervačné systémy, dashboardy, formuláre s komplexnou validáciou, live vyhľadávanie a filtrovanie — všetko v rámci monolitickej Laravel aplikácie.

Inštalácia Livewire 3

Livewire 3 vyžaduje Laravel 10+ a PHP 8.1+. Inštalácia cez Composer pridá Blade direktívy a automaticky zaregistruje middleware.

composer require livewire/livewire

# Voliteľné: publikovať konfiguráciu
php artisan livewire:publish --config

Do hlavného Blade layoutu pridajte Livewire skripts a štýly — Livewire 3 ich vkladá automaticky cez @livewireScripts@livewireStyles, alebo môžete použiť nový @livewire tag:

<!-- resources/views/layouts/app.blade.php -->
<html>
<head>
    @livewireStyles
</head>
<body>
    {{ $slot }}
    @livewireScripts
</body>
</html>

Prvý komponent — živé vyhľadávanie

Komponent pozostáva z dvoch súborov: PHP triedy a Blade šablóny. Vytvoríme ich jedným príkazom:

php artisan make:livewire ProductSearch

Toto vytvorí app/Livewire/ProductSearch.php a resources/views/livewire/product-search.blade.php.

<?php
// app/Livewire/ProductSearch.php
namespace App\Livewire;

use Livewire\Component;
use Livewire\WithPagination;
use App\Models\Product;

class ProductSearch extends Component
{
    use WithPagination;

    public string $search = '';
    public string $category = 'all';

    // Každá zmena $search automaticky resetuje stránkovanie
    public function updatingSearch(): void
    {
        $this->resetPage();
    }

    public function render()
    {
        return view('livewire.product-search', [
            'products' => Product::query()
                ->when($this->search, fn($q) => $q->where('name', 'like', "%{$this->search}%"))
                ->when($this->category !== 'all', fn($q) => $q->where('category', $this->category))
                ->paginate(12),
        ]);
    }
}
<!-- resources/views/livewire/product-search.blade.php -->
<div>
    <input
        wire:model.live.debounce.300ms="search"
        type="search"
        placeholder="Hľadať produkt..."
        class="w-full px-4 py-2 rounded-lg bg-gray-800 border border-gray-700"
    >

    <div class="grid grid-cols-3 gap-4 mt-6">
        @foreach($products as $product)
            <div wire:key="{{ $product->id }}" class="card">
                <h3>{{ $product->name }}</h3>
                <p>{{ $product->price }} EUR</p>
            </div>
        @endforeach
    </div>

    {{ $products->links() }}
</div>
wire:model.live vs. wire:model.blur.live posiela AJAX request pri každom stlačení klávesy (s debounce), .blur až po opustení poľa. Pre vyhľadávanie použite .live.debounce.300ms, pre formulárové polia .blur.

Properties, Actions a Lifecycle hooks

Livewire komponent je PHP trieda so verejnými properties (automaticky synchrónizované s frontendom) a metódami (volateľné cez wire:click).

class ShoppingCart extends Component
{
    public array $items = [];
    public float $discount = 0;

    // Lifecycle hook — volá sa pred každým hydrate
    public function boot(): void
    {
        // Inicializácia závislostí
    }

    // Action — volá sa cez wire:click="addItem(productId)"
    public function addItem(int $productId): void
    {
        $product = Product::findOrFail($productId);
        $this->items[] = ['id' => $product->id, 'name' => $product->name, 'price' => $product->price];

        // Dispatch browser event pre Alpine.js / JavaScript
        $this->dispatch('cart-updated', count: count($this->items));
    }

    // Computed property (Livewire 3) — cachovaná v rámci jedného requestu
    #[\Livewire\Attributes\Computed]
    public function total(): float
    {
        return collect($this->items)->sum('price') * (1 - $this->discount / 100);
    }
}

Formuláre a validácia

Livewire 3 prináša dedikovanú Form Object triedu — ideálne pre zložité formuláre s validáciou a resetovaním stavu.

<?php
// app/Livewire/Forms/ContactForm.php
namespace App\Livewire\Forms;

use Livewire\Form;

class ContactForm extends Form
{
    public string $name = '';
    public string $email = '';
    public string $message = '';

    protected function rules(): array
    {
        return [
            'name'    => 'required|min:2|max:100',
            'email'   => 'required|email',
            'message' => 'required|min:20|max:2000',
        ];
    }

    public function submit(): void
    {
        $this->validate();
        // Odoslanie e-mailu, uloženie do DB...
        $this->reset();
    }
}
// app/Livewire/ContactPage.php
class ContactPage extends Component
{
    public ContactForm $form;

    public bool $submitted = false;

    public function submit(): void
    {
        $this->form->submit();
        $this->submitted = true;
    }
}
<!-- Blade template -->
<form wire:submit="submit">
    <input wire:model.blur="form.email" type="email">
    @error('form.email') <span class="text-red-400">{{ $message }}</span> @enderror

    <button type="submit" wire:loading.attr="disabled">
        <span wire:loading.remove>Odoslať</span>
        <span wire:loading>Odosielam...</span>
    </button>
</form>

@if($submitted)
    <div class="bg-green-500/20 text-green-400 p-4 rounded-lg">Správa odoslaná!</div>
@endif

Real-time s Laravel Reverb a Echo

Pre skutočný real-time (WebSocket, nie polling) Livewire 3 spolupracuje s Laravel Reverb — novým first-party WebSocket serverom od Laravel 11+.

# Inštalácia Reverb
composer require laravel/reverb
php artisan reverb:install

# Spustenie WebSocket servera
php artisan reverb:start
// Emitovanie eventu z backend kódu (napr. Job)
use App\Events\OrderStatusUpdated;
broadcast(new OrderStatusUpdated($order));

// V Livewire komponente — počúvanie na broadcast event
class OrderTracker extends Component
{
    public Order $order;

    #[\Livewire\Attributes\On('echo:orders.{order.id},OrderStatusUpdated')]
    public function refreshOrder(): void
    {
        $this->order->refresh();
    }
}
Polling ako jednoduchá alternatíva: Ak nechcete nastavovať WebSocket server, Livewire 3 podporuje polling cez wire:poll.5s atribút priamo v Blade šablóne. Pre dashboardy s aktualizáciou každých niekoľko sekúnd je to dostačujúce riešenie.

Alpine.js + Livewire — perfektná kombinácia

Livewire 3 je dodávaný s Alpine.js zabudovaným — nie je potrebná samostatná inštalácia. Alpine rieši lokálny UI stav (modálne okná, dropdown, animácie), Livewire rieši serverový stav (databáza, validácia, autentifikácia).

<!-- Modálne okno riadené Alpine.js, obsah načítaný cez Livewire -->
<div x-data="{ open: false }">
    <button @click="open = true">Detail produktu</button>

    <div x-show="open" @keydown.escape.window="open = false">
        <!-- Livewire komponent sa inicializuje keď je open=true -->
        @if($open)
            <livewire:product-detail :productId="$product->id" />
        @endif
        <button @click="open = false">Zavrieť</button>
    </div>
</div>
<!-- Komunikácia Livewire → Alpine cez $dispatch -->
<!-- V Livewire PHP: $this->dispatch('show-toast', message: 'Uložené!') -->
<div x-data="{ message: '' }" @show-toast.window="message = $event.detail.message">
    <div x-show="message" x-text="message"></div>
</div>

Lazy loading komponentov

Livewire 3 podporuje lazy loading — komponent sa načíta až po prvom renderi stránky. Ideálne pre drahé databázové operácie, ktoré nie sú kritické pre prvé zobrazenie.

<!-- Lazy loading s placeholder -->
<livewire:sales-chart lazy>
    <!-- Placeholder kým sa komponent nenačíta -->
    <div class="animate-pulse bg-gray-800 h-64 rounded-xl"></div>
</livewire:sales-chart>
// V PHP triede označte metódu pre placeholder
class SalesChart extends Component
{
    public function placeholder()
    {
        return view('livewire.placeholders.chart-skeleton');
    }

    public function render()
    {
        // Táto metóda sa zavolá až po lazy načítaní
        return view('livewire.sales-chart', [
            'data' => $this->calculateExpensiveChartData(),
        ]);
    }
}

Testovanie Livewire komponentov

Livewire 3 prináša Livewire::test() helper, ktorý simuluje celý životný cyklus komponentu vrátane AJAX requestov — bez potreby skutočného prehliadača.

use Livewire\Livewire;
use App\Livewire\ProductSearch;

it('filtruje produkty podľa vyhľadávania', function () {
    Product::factory()->create(['name' => 'Laravel kurz']);
    Product::factory()->create(['name' => 'PHP kniha']);

    Livewire::test(ProductSearch::class)
        ->set('search', 'Laravel')
        ->assertSee('Laravel kurz')
        ->assertDontSee('PHP kniha');
});

it('volá submit akciu a validuje formulár', function () {
    Livewire::test(ContactPage::class)
        ->set('form.email', 'neplatny-email')
        ->call('submit')
        ->assertHasErrors(['form.email' => 'email'])
        ->assertNotDispatched('contact-submitted');
});

Performance: wire:key a dôležité optimalizácie

Niekoľko pravidiel, ktoré zabránia zbytočným re-renderom a pomalým AJAX requestom:

Pozor na N+1 v render(): Metóda render() sa volá pri každom AJAX requeste komponentu. Používajte with(['products' => ...]) so správnymi eager loads a kešovaním, aby každý klik nezahlcoval databázu.

Záver: Livewire 3 ako default voľba pre Laravel projekty

Livewire 3 výrazne znížil overhead fullstack vývoja pre PHP tímy. Ak vaša aplikácia nevyžaduje offline podporu, komplexný real-time (napr. multiplayer) alebo separátny mobilný klient, Livewire 3 vám ušetrí dni vývoja oproti Inertia.js + React.

Kombinovaný s Alpine.js pre lokálny UI stav a Laravel Reverb pre WebSocket pokryje 90 % prípadov použitia modernej webovej aplikácie — a ostanete v PHP ekosystéme, ktorý poznáte.

Potrebujete Laravel alebo Livewire vývoj?

Postavím vám reaktívnu Laravel aplikáciu s Livewire 3 — od architektúry komponentov po nasadenie. Cenová ponuka do 24 hodín.

Nezáväzný dopyt

Ďalšie články

Zavolať E-mail Dopyt

Ochrana súkromia

Táto stránka využíva cookies pre nevyhnutné fungovanie. Rešpektujeme vaše súkromie a legislatívu GDPR.