Livewire 3 a 4 — čo sa zmenilo
Všetko, čo sa zmenilo medzi Livewire 3 a Livewire 4: nové možnosti, ktoré sa oplatí prevziať, každá nekompatibilná zmena s kódom „predtým / potom“ a kontrolný zoznam samotného upgradu. Vrátane troch zmien, ktoré prejdú vašimi testami a pokazia produkciu.
1. Stručne
Livewire 4 je veľké vydanie s malou cestou upgradu. Model komponentu sa nezmenil: PHP trieda, Blade šablóna, stav na serveri, HTML po drôte. Zmenilo sa to, kde komponenty žijú, ako sa píšu a akú časť stránky zasiahne jedna aktualizácia.
Čo získate
- Jednosúborové komponenty — trieda a značkovanie v jednom súbore.
- Ostrovy — oblasti s nezávislým vykresľovaním, bez rozpadu na podkomponenty.
- Sloty — rodič vkladá značkovanie do potomka, vyhodnocuje sa v kontexte rodiča.
- Optimistické UI —
wire:show,wire:text,wire:bindmenia DOM bez round tripu. - Drag and drop —
wire:sort, bez externej knižnice. - Scoped CSS — štýly komponentu, ktoré nepretekajú.
Čo vás podrazí
- Neuzavreté tagy
<livewire:…>sa ticho nevykreslia. - Modifikátory
wire:modelzmenili význam — polia prestanú synchronizovať. - Endpoint aktualizácií sa presunul na
/livewire-{hash}/— lámu sa infraštruktúrne pravidlá. - Modifikátory
wire:transitionboli odstránené. - Volt sa stal súčasťou jadra.
2. Porovnanie vedľa seba
| Oblasť | Livewire 3 | Livewire 4 |
|---|---|---|
| Súbory komponentu | app/Livewire/Counter.php + resources/views/livewire/counter.blade.php |
resources/views/components/⚡counter.blade.php (jeden súbor) |
| Príkaz na vytvorenie | php artisan livewire:make Counter |
php artisan make:livewire counter |
| Smerovanie | Route::get('/x', Dashboard::class) |
Route::livewire('/x', 'pages::dashboard') |
| Čiastočné vykresľovanie | Rozpad na podkomponenty | Oblasti @island |
| Sloty | Nepodporované | {{ $slot }}, <wire:slot name="…"> |
| Drag and drop | SortableJS plus lepiaci kód | wire:sort |
| Okamžité UI | Alpine.js ručne | wire:show, wire:text, wire:bind |
| CSS komponentu | Globálny stylesheet | Scoped <style> v komponente |
| Paralelné akcie | Nedostupné | #[Async], wire:click.async |
| Endpoint aktualizácií | /livewire/update |
/livewire-{hash}/update |
| JS hooky | Livewire.hook('request'|'commit') |
interceptRequest(), interceptMessage() |
| Volt | Samostatný balík | Súčasť jadra |
| Testovanie | PHPUnit alebo Pest | Odporúčaný Pest, testy môžu ležať vedľa komponentu |
3. Upgrade krok za krokom
# 1. Zdvihnúť závislosť
composer require livewire/livewire:^4.0
# 2. Vyčistiť všetky cache
php artisan optimize:clear
# 3. Spustiť testy skôr, než sa dotknete čohokoľvek ďalšieho
php artisan testLaravel Shift zautomatizuje veľkú časť mechanickej práce. Či ho použijete alebo nie, prejdite si potom kontrolný zoznam nižšie — tiché zlyhania nástroj označí najhoršie.
Poradie prác, ktoré zvyčajne prebehne hladko
- Aktualizovať balík a vyčistiť cache.
- Opraviť premenovania v konfigurácii (kapitola 4).
- Opraviť smerovanie (kapitola 5).
- Nájsť v kóde neuzavreté tagy komponentov (kapitola 6).
- Skontrolovať každý
wire:models modifikátorom (kapitola 7). - Aktualizovať infraštruktúrne pravidlá pre nový endpoint (kapitola 8).
- Nahradiť odstránené modifikátory
wire:transition(kapitola 9). - Migrovať komponenty Volt, ak ste ho používali (kapitola 12).
- Spustiť testy znova a prejsť aplikáciu v prehliadači.
- Až potom sa pustiť do ostrovov, slotov a jednosúborových komponentov.
4. Premenovania v konfigurácii
| Livewire 3 | Livewire 4 | Poznámka |
|---|---|---|
layout | component_layout | Používa namespace layouts:: |
lazy_placeholder | component_placeholder | — |
smart_wire_keys | smart_wire_keys | Predvolená hodnota sa zmenila z false na true |
| — | component_locations | Priečinky prehľadávané kvôli komponentom |
| — | component_namespaces | Pomenované korene, napríklad pages:: |
| — | make_command | Jednosúborová alebo triedna generácia |
| — | csp_safe | Build pre prísnu CSP |
'component_layout' => 'layouts::app',
'component_placeholder' => 'livewire.placeholder',
'component_locations' => [
'resources/views/components',
'resources/views/livewire',
],
'component_namespaces' => [
'pages' => 'resources/views/pages',
],
// Naďalej generovať triedne komponenty
'make_command' => [
'type' => 'class',
],5. Smerovanie
use App\Livewire\Dashboard;
Route::get('/dashboard', Dashboard::class)
->middleware('auth')
->name('dashboard');use App\Livewire\Dashboard;
Route::livewire('/dashboard', Dashboard::class)
->middleware('auth')
->name('dashboard');
// Alebo podľa mena komponentu
Route::livewire('/dashboard', 'pages::dashboard')
->middleware('auth')
->name('dashboard');grep -rn "Route::get(.*::class" routes/.
6. Tagy komponentov musia byť uzavreté
<livewire:user-profile>
<livewire:order-list><livewire:user-profile />
<livewire:order-list /># Tagy komponentov, ktoré nie sú samouzatvorené
grep -rn "<livewire:[^>]*[^/]>" resources/views/
# Forma cez direktívu @livewire() nie je dotknutá
grep -rn "@livewire(" resources/views/7. wire:model sa zmenil dvakrát
7.1 Modifikátory riadia synchronizáciu na klientovi
<input wire:model.blur="title">
<select wire:model.change="status"><input wire:model.live.blur="title">
<select wire:model.live.change="status">7.2 Už žiadne bublanie z potomkov
<div wire:model="value">
<input type="text">
</div><div wire:model.deep="value">
<input type="text">
</div># Každý wire:model s modifikátorom
grep -rn "wire:model\.[a-z]" resources/views/
# wire:model na inom prvku než input je kandidát na problém s bublaním
grep -rn "<div[^>]*wire:model" resources/views/8. Endpoint aktualizácií sa presunul
Všetky URL Livewire teraz obsahujú hash: /livewire/ sa stalo /livewire-{hash}/.
Kde skontrolovať
- Bloky
locationv nginxe alebo Apachi - Whitelisty WAF a firewallu
- Pravidlá obchádzania cache CDN
- Rate limitery viazané na cestu
- Smerovacie pravidlá load balancera
- Monitoring a uptime kontroly
- Záznamy
connect-srcv CSP
location /livewire/ {
# …
}location ~ ^/livewire(-[a-z0-9]+)?/ {
# …
}9. wire:transition bol prestavaný
<div wire:transition.opacity.duration.300ms>
…
</div><div wire:transition>
…
</div>::view-transition-old(root),
::view-transition-new(root) {
animation-duration: 300ms;
}10. Zmeny v PHP API
Streaming
$this->stream(to: '#container', content: 'Hello', replace: true);$this->stream('Hello', replace: true, el: '#container');Mountovanie komponentu
mount($name, $params = [], $key = null)mount($name, $params = [], $key = null, $slots = [])Nové atribúty
| Atribút | Účel |
|---|---|
#[Async] | Vykonať akciu paralelne |
#[Renderless] | Preskočiť prekreslenie po akcii |
#[Prop] | Deklarovať vlastnosť ako props od rodiča |
#[Json] | Vrátiť dáta priamo do JavaScriptu |
11. Zmeny v JavaScript API
$wire.$js('showToast', { message: 'Uložené' });$wire.$js.showToast = { message: 'Uložené' };Hooky sa stali interceptormi
document.addEventListener('livewire:init', () => {
Livewire.hook('request', ({ options, fail }) => {
options.headers['X-Tenant'] = window.tenantId;
fail(({ status, preventDefault }) => {
if (status === 419) {
preventDefault();
window.location.reload();
}
});
});
});document.addEventListener('livewire:init', () => {
Livewire.interceptRequest(({ options, fail }) => {
options.headers['X-Tenant'] = window.tenantId;
fail(({ status, preventDefault }) => {
if (status === 419) {
preventDefault();
window.location.reload();
}
});
});
Livewire.interceptMessage(({ component, succeed }) => {
succeed(() => {
console.debug('komponent aktualizovaný', component.name);
});
});
});{{-- Validačné chyby na klientovi --}}
<div x-show="$errors.has('email')" x-text="$errors.first('email')"></div>12. Volt sa stal súčasťou jadra
| Volt | Livewire 4 |
|---|---|
Livewire\Volt\Component | Livewire\Component |
Volt::route() | Route::livewire() |
Volt::test() | Livewire::test() |
| Service provider Volt | Odstrániť |
Balík livewire/volt | Odstrániť závislosť |
composer remove livewire/volt<?php
use Livewire\Volt\Component;
new class extends Component {
public string $title = '';
};
?>
<div>…</div><?php
use Livewire\Component;
new class extends Component {
public string $title = '';
};
?>
<div>…</div>13. Osvojenie nových možností
1. Ostrovy na najpomalšej stránke
<div>
<div class="card">Tržby: {{ $this->revenue }}</div>
<div class="card">Úloh vo fronte: {{ $this->queue }}</div>
<div class="card">Posledná aktivita: …</div>
</div><div>
@island(name: 'revenue')
<div class="card">Tržby: {{ $this->revenue }}</div>
@endisland
@island(name: 'queue', poll: '5s')
<div class="card">Úloh vo fronte: {{ $this->queue }}</div>
@endisland
@island(name: 'activity', lazy: true)
@placeholder
<div class="card skeleton animate-pulse h-48"></div>
@endplaceholder
<div class="card">Posledná aktivita: …</div>
@endisland
</div>2. Nahradiť round trip klientskými direktívami
<button wire:click="$toggle('showFilters')">Filtre</button>
@if ($showFilters)
<div class="filters">…</div>
@endif<button wire:click="$toggle('showFilters')">Filtre</button>
<div class="filters" wire:show="showFilters">…</div>3. Zahodiť SortableJS
<ul wire:sort="reorder">
@foreach ($tasks as $task)
<li wire:sort:item="{{ $task->id }}" wire:key="task-{{ $task->id }}">
<span wire:sort:handle>⠿</span> {{ $task->title }}
</li>
@endforeach
</ul>4. Zlúčiť podkomponenty vytvorené len kvôli vykresľovaniu
Ak potomok nemá vlastný stav a nepoužíva sa opakovane, ostrov v rodičovi je ľahší — jeden komponent, jedna trieda, jeden snapshot.
5. #[Renderless] pre neviditeľnú prácu
use Livewire\Attributes\Renderless;
#[Renderless]
public function trackView(): void
{
$this->post->increment('views');
}6. Prevod na jednosúborový formát — až nakoniec
Je to kozmetika. Robte to príležitostne, keď súbor aj tak upravujete, nie ako samostatný migračný šprint.
14. Kontrolný zoznam upgradu
Pred začiatkom
- Testy prechádzajú na Livewire 3.
- Samostatná vetva a záloha databázy, ak je prostredie zdieľané.
- Niekto pripravený prejsť aplikáciu ručne — tiché zlyhania vidí len človek.
Mechanické zmeny
composer require livewire/livewire:^4.0php artisan optimize:clearlayout→component_layoutlazy_placeholder→component_placeholderRoute::get(…, Component::class)→Route::livewire(…)- Všetky tagy
<livewire:…>samouzatvorené wire:model.blur/.change→ pridať.livewire:modelna obale → pridať.deepwire:scroll→wire:navigate:scroll- Modifikátory
wire:transition→ do CSS - Poradie argumentov
$this->stream() $wire.$js('name', …)→$wire.$js.name = …Livewire.hook(…)→interceptRequest()/interceptMessage()- Triedy, routy, testy a balík Volt odstránené
Infraštruktúra
- Location bloky nginx / Apache rozšírené na
/livewire-{hash}/ - Pravidlá WAF, CDN a firewallu aktualizované
- Rate limitery a monitoring presmerované
connect-srcv CSP prehodnotený
Overenie
- Testy zelené
- Všetky formuláre sa odosielajú a validujú
- Nahrávanie súborov funguje vrátane indikátora priebehu
- Tabuľky stránkujú, radia a filtrujú
- Modálne okná sa otvárajú a zatvárajú
- Widgety tretích strán v
wire:ignoresa inicializujú - Konzola prehliadača čistá na hlavných tokoch
- Aktualizačné požiadavky vracajú 200 v produkcii, nie 403 z WAF
Oficiálne zdroje
- Upgrade guide: livewire.laravel.com/docs/upgrading
- Dokumentácia Livewire: livewire.laravel.com/docs