Увійти Реєстрація
Блог Серії
Кар'єра
Вакансії Компанії
Навчання
Документація Співбесіди Тестування Відео
Екосистема
Пакети Ресурси Проєкти Інструменти Події
Інше
Про нас Реклама

Як виконати JavaScript з Livewire-компонента: #[Js] і $this->js()?

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 у браузері.

Докладніше в документації: Атрибут Js

Схожі питання