Livewire дає два способи виконати JavaScript, і вони вирішують різні задачі.
1. #[Js] - метод, що виконується в браузері без запиту. PHP-метод повертає рядок JavaScript; при виклику з шаблону сервер не задіюється:
use Livewire\Attributes\Js;
new class extends Component {
public string $title = '';
public string $content = '';
#[Js]
public function clearForm(): string
{
return <<<'JS'
$wire.title = ''
$wire.content = ''
JS;
}
};
<button type="button" wire:click="clearForm">Очистити</button>
Очищення полів відбувається миттєво. Код JavaScript потрапляє в сторінку під час рендеру, тож на клік не потрібен мережевий запит.
2. $this->js() - виконати JavaScript після дії на сервері:
public function save(): void
{
$this->form->save();
$this->js("document.getElementById('comment-form').reset()");
$this->js('$wire.$refresh()');
}
Код ставиться в чергу й виконується, коли відповідь прийде в браузер.
3. Скрипти в шаблоні (Livewire 4): тег <script> у шаблоні однофайлового чи багатофайлового компонента виконується з this = $wire, без обгортки @script:
<script>
this.$js.focusSearch = () => this.$refs.search.focus();
</script>
<input wire:ref="search">
<button type="button" wire:click="$js.focusSearch">Пошук</button>
Такі скрипти віддаються окремими кешованими файлами.
Коли що:
- суто клієнтська дія (очистити, згорнути, сфокусуватися) -
#[Js]чи$jsу скрипті компонента; - реакція на результат серверної дії (прокрутити до нового коментаря, закрити вікно, сповіщення) -
$this->js()або подія, яку слухає JavaScript; - переважно клієнтська логіка - Alpine, а не JavaScript, згенерований у PHP.
Пастки:
- не вставляйте дані користувача в рядок JavaScript -
$this->js("alert('{$this->name}')")з ім'ям'); stealCookies(); ('виконає чужий код. Дані передавайте через подію з параметрами чиJs::from($value)для безпечного екранування; - CSP: з увімкненим
csp_safeскладні вирази JavaScript у директивах обмежені - перевірте сумісність, якщо сайт використовує суворий Content Security Policy; #[Js]-метод не має доступу до PHP-стану на момент кліку - лише до того, що є в$wireу браузері.