• Время чтения ~5 мин
  • 01.06.2022

Laravel Livewire — отличный инструмент для достижения динамического поведения на странице без непосредственного написания кода JavaScript. И, как у любого инструмента, у него есть много «скрытых жемчужин», как в официальной документации, так и в дополнительных практических советах, предоставленных разработчиками. Некоторые из них я решил собрать в этой статье. Давайте разбираться!

1.Не требуется рендер()

Типичный метод 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 по умолчанию.Затем вам может понадобиться привязать его имя к фактическому местоположению.

Обычно это делается в методе boot() app/Providers/AppServiceProvider.php (или любого поставщика услуг):

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, но вместо этого хотите указать «Product», а также решили поместить его во вложенную папку, вы можете выполнить следующую команду:< /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