При SPA-переході через wire:navigate вміст <body> замінюється новим. Але деякі елементи не повинні перестворюватися: аудіо- чи відеоплеєр, що грає, чат-віджет, бічна панель з прокручуванням.
@persist позначає елемент, який Livewire переносить на нову сторінку замість заміни:
{{-- resources/views/layouts/app.blade.php --}}
<body>
<main>{{ $slot }}</main>
@persist('player')
<audio src="{{ $episode->file }}" controls></audio>
@endpersist
@livewireScripts
</body>
Якщо на новій сторінці є @persist з тією самою назвою, Livewire бере існуючий DOM-елемент зі старої сторінки й ставить на місце нового. Відтворення не переривається, зберігаються стан Alpine, обробники подій і значення полів.
Умови:
- працює лише з
wire:navigate- при звичайному переході чи оновленні сторінки все завантажується заново; - елемент з тією самою назвою має бути на обох сторінках. Найпростіше - розмістити його в спільному макеті;
- розміщувати поза Livewire-компонентами сторінки, зазвичай прямо в макеті. Вміст, який має оновлюватися з сервера, не варто «заморожувати».
Прокрутка всередині збереженого елемента (довга бічна навігація) - wire:navigate:scroll:
@persist('sidebar')
<aside class="overflow-y-auto" wire:navigate:scroll>...</aside>
@endpersist
У Livewire 3 для цього був wire:scroll - при оновленні до v4 його треба перейменувати.
Підводні камені:
- збережений елемент не оновлюється. Якщо в ньому показано «Активний пункт меню» чи лічильник, після переходу вони лишаться старими. Активне посилання в збереженій навігації позначається через
data-current/wire:current- Livewire оновлює їх при навігації; - назва має бути унікальною й стабільною - різні елементи з однією назвою на різних сторінках підмінять один одного;
- персональні дані в збереженому елементі (наприклад, після виходу з облікового запису через
wire:navigate) переживуть перехід - вихід краще робити повним перезавантаженням сторінки.