• Час читання ~3 хв
  • 01.06.2022

Laravel Livewire – чудовий інструмент для досягнення динамічної поведінки на сторінці без безпосереднього написання коду JavaScript. І, як і будь-який інструмент, він має багато «прихованих дорогоцінних каменів», як в офіційних документах, так і практичних додаткових порад, наданих розробниками. Деякі з них я вирішив зібрати в цій статті. Давайте розберемося!

1.Render() не потрібен

Звичайний метод render() виглядає приблизно так:

// app/Http/Livewire/PostsShow.php
class PostsShow extends Component
{
    public function render()
    {
        return view('livewire.posts-show');
    }
}

Але якщо ваш метод render() є лише одним рядком для відображення за умовчанням, ви можете видалити цей render() метод із компонента, і все це працюватиме, завантажуючи стандартний render() із методу постачальника.

class PostsShow extends Component
{
    // This empty component will still work and load the Blade file
}

2.Компоненти в підпапках

Якщо ви хочете створити компонент у підпапці, наприклад app/Http/Livewire/Folder/Component.php, у вас є два способи, як це зробити:

php artisan make:livewire Folder/Component

або

php artisan make:livewire folder.component

Зверніть увагу, що перший спосіб – перша літера з великого регістру, а другий – нижній.В обох випадках буде створено два файли:

  • app/Http/Livewire/Folder/Component.php
  • resources/views/livewire/folder/component.blade.php

Підтеки будуть створені автоматично, якщо їх не існує.


3. Компоненти в папці не за замовчуванням

Якщо ви використовуєте якийсь зовнішній пакет з компонентами Livewire, можливо, ваш компонент Livewire знаходиться в іншій папці, ніж app/Http/Livewire за умовчанням.Потім, можливо, знадобиться прив’язати його назву до фактичного розташування.

Як правило, це робиться за допомогою методу app/Providers/AppServiceProvider.php (або будь-якого постачальника послуг) boot():

class AppServiceProvider extends ServiceProvider
{
    public function boot()
    {
        Livewire::component('shopping-cart', \Modules\Shop\Http\Livewire\Cart::class);
    }
}

4. Легко перейменуйте або переміщуйте компоненти

Якщо ви зробили помилку під час створення компонента за допомогою make:livewire, не хвилюйтеся.Вам не потрібно перейменовувати два файли вручну, для цього є команда.

Наприклад, якщо ви написали php artisan make:livewire Prduct, але замість цього бажаєте «Продукт», а також вирішили помістити його у підпапку, ви можете виконати цю команду:< /p>

php artisan livewire:move Prduct Products/Show

Результат буде таким:

COMPONENT MOVED

CLASS: app/Http/Livewire/Prduct.php
    => app/Http/Livewire/Products/Show.php
VIEW:  resources/views/livewire/prduct.blade.php
    => resources/views/livewire/products/show.blade.php

5.

Приклад stubs/livewire.stub:

Наприклад, якщо ви хочете створити компоненти без методу render(), просто видаліть його з файлу-заглушки, а потім щоразу, коли ви запускаєте php artisan make:livewire Component , він візьме шаблон із вашої оновленої загальнодоступної заглушки.

php artisan livewire:stubs

6.Не створюйте метод лише для встановлення значення

Якщо у вас є подія кліку, яка встановить деяке значення певної властивості, ви можете зробити щось на кшталт цього:

<?php
 
namespace [namespace];
 
use Livewire\Component;
 
class [class] extends Component
{
    public function render()
    {
        return view('[view]');
    }
}

А потім


Але насправді ви можете призначити нове значення властивості Livewire безпосередньо зі свого файлу Blade, не маючи окремого методу в компоненті Livewire.

Ось код:

<button wire:click="showText">Show</button>

Отже, ви викликаєте $set і вказуєте два параметри: назву властивості та нове значення.

class Show extends Component
{
    public $showText = false;
 
    public function showText() {
        $this->showText = true;
    }
}

7.Ще далі: легко встановлювати значення True/False

Дотримуючись останньої поради, якщо ваша властивість є булевою змінною зі значеннями true/false, і ви хочете мати кнопку показати/приховати, ви можете зробити щось на зразок цього:

<button wire:click="$set('showText', true)">Show</button>

Примітка. Особисто я б уникав використання Livewire для таких простих ефектів перемикання, оскільки він додає до сервера додатковий запит.


Натомість для цього краще використовувати JavaScript, наприклад Alpine.js:

8. Три способи мінімізації запитів сервера

<button wire:click="$toggle('showText')">Show/Hide</button>

Одною з головних критики Livewire є те, що він виконує занадто багато запитів до сервера. Якщо у вас є wire:model у полі введення, кожне натискання клавіші потенційно може викликати сервер для повторного відтворення компонента.Це дуже зручно, якщо у вас є деякі ефекти в режимі реального часу, як-от «пошук у реальному часі». Але зазвичай запити сервера можуть бути досить дорогими з точки зору продуктивності.

Однак цю поведінку wire:model дуже легко налаштувати.

<div x-data="{ open: false }">
    <button @click="open = true">Expand</button>
 
    <span x-show="open">
      Content...
    </span>
</div>

9.Налаштувати атрибути перевірки

Перевірка Livewire працює дуже подібно до механізму перевірки Laravel, але з деякими відмінностями. У Laravel, якщо ви хочете налаштувати назви атрибутів, ви можете визначити attributes() метод у класі Form Request.

Те, що описано в офіційній документації, але досить рідко використовується, як я бачив. Якщо певна дія займає деякий час на екрані, варто показати якийсь індикатор завантаження, як-от крутиться gif, або просто текст "Завантаження даних..."

  1. wire:model.debounce: by default, Livewire waits for 150ms after the keystroke on the input, before performing the request to the server. But you can override it: <input type="text" wire:model.debounce.1000ms="propertyName">

  2. wire:model.lazy: by default, Livewire is listening for all events on the input, and then performs the server requests. By providing a lazy directive, you tell Livewire to listen only to the change event. It means that the user may keep typing and changing the value, and the server request will be fired only when the user clicks away from that field.

  3. wire:model.defer: this will not fire the server requests on the change of the input. It will save the new value internally and will pass it to the next network request, which may come from other input fields or other button clicks.


У Livewire це дуже легко не тільки впровадити, але й налаштувати.

Найпростіший приклад обробки даних: коли запит сервера зроблено, він відображатиме текст "Обробка платежу...", доки запит сервера не буде завершено і не буде отримано результат.

На практиці мені подобається показувати такі індикатори завантаження, лише якщо це займає деякий час. Немає сенсу повторно відображати DOM щоразу, у всіх можливих випадках.Що робити, якщо ми зробимо це лише якщо запит займає більше 500 мс?

class ContactForm extends Component
{
    protected $validationAttributes = [
        'email' => 'email address'
    ];
 
    // ...

Легко:


Також є можливості пограти з класами CSS для завантаження станів, приєднати їх до конкретних дій тощо: читайте в офіційні документи.

11.Індикатор офлайн

Ще одна задокументована, але менш відома функція Livewire – повідомляє користувачеві, якщо його з’єднання з Інтернетом втрачено. Це може бути корисно, якщо ваша програма працює з даними в режимі реального часу або з кількома оновленнями на екрані: ви можете розмити деякі частини веб-сторінки та показати «офлайновий» текст.

Це так просто:

<div>
    <button wire:click="checkout">Checkout</button>
 
    <div wire:loading>
        Processing Payment...
    </div>
</div>

Також, як я вже згадував, ви можете розмити деякі елементи, призначивши класи CSS, наприклад:

12. Розбиття на сторінки за допомогою Bootstrap Framework

<div wire:loading.delay.longer>...</div>

Як і Laravel, Livewire за замовчуванням використовує стиль розбиття сторінок із фреймворку Tailwind.На щастя, його легко змінити, просто введіть інше значення властивості:


Ви можете перевірити доступні дизайни сторінок безпосередньо в репозиторії Livewire Github. Переглядаючи це, я не знайшов жодної інформації про те, чи використовується версія Bootstrap 4 чи Bootstrap 5.

13.Без кріплення: автоматичне прив’язування моделі маршруту

Якщо ви хочете передати об’єкт компоненту Livewire, це типовий спосіб зробити це за допомогою методу mount():

<div wire:offline>
    You are now offline.
</div>

Тоді десь у Blade у вас є @livewire('show-post', $post).

<div wire:offline.class="bg-red-300"></div>

Є кілька можливих рішень для цього, мабуть, найелегантнішим є зупинити подію Livewire ще до того, як вона відбудеться:

Цей event.stopImmediatePropagation() зупинить виклик методу Livewire, якщо результат підтвердження хибний.

class ShowPosts extends Component
{
    use WithPagination;
 
    protected $paginationTheme = 'bootstrap';

Ви можете знайти кілька інших можливих рішень у це обговорення проблеми Github.


Ось і все, менш відомі функції Livewire та невеликі поради. Сподіваюся, це було корисно!

class ShowPost extends Component
{
    public $post;
 
    public function mount(Post $post)
    {
        $this->post = $post;
    }
}
class ShowPost extends Component
{
    public Post $post;
}

<button wire:click="delete($post->id)"
        onclick="return confirm('Are you sure?')">Delete</button>
<button onclick="confirm('Are you sure?') || event.stopImmediatePropagation()"
        wire:click="delete($post->id)">Delete</button>

Comments

No comments yet
Yurij Finiv

Yurij Finiv

Full stack

Про мене

Professional Fullstack Developer with extensive experience in website and desktop application development. Proficient in a wide range of tools and technologies, including Bootstrap, Tailwind, HTML5, CSS3, PUG, JavaScript, Alpine.js, jQuery, PHP, MODX, and Node.js. Skilled in website development using Symfony, MODX, and Laravel. Experience: Contributed to the development and translation of MODX3 i...

Про автора CrazyBoy49z
WORK EXPERIENCE
Контакти
Ukraine, Lutsk
+380979856297