• Время чтения ~4 мин
  • 21.07.2023

Вживую на сцене в Laracon Калеб Порцио только что выпустил официальную бета-версию Livewire v3! В своем выступлении он продемонстрировал массу новых функций, о некоторых из которых мы расскажем здесь.

Переписанное ядро

Ядро Livewire было полностью переписано с нуля. Переписывание ядра было огромным делом, но необходимо было выполнить все, что включено в этот выпуск. Новая базовая архитектура также будет намного проще в обслуживании для Калеба и основных участников Livewire.

Использование

Alpine Ядро v3 теперь использует Alpine в полной мере. Вместо того, чтобы включать код для применения обновлений DOM, добавления прослушивателей событий и т. д., как в Livewire, так и в Alpine, Livewire v3 использует Alpine для тяжелой работы. Зарегистрировав плагины Alpine, Livewire теперь позволяет Alpine выполнять тяжелую работу, сохраняя при этом синтаксический сахар, который вы полюбили.

Это также означает, что Alpine теперь включен по умолчанию в Livewire, поэтому нет необходимости загружать Alpine через CDN или NPM. Он впрыскивается автоматически.

Кроме того, v3 использует плагин Alpine Morph для дифференциации DOM и применения обновлений вместо morphdom. Это приведет к меньшему количеству проблем с различиями в DOM и в целом улучшит совместимость между Livewire и Alpine.

Улучшенная вложенность

компонентов В прошлом я считал вложение компонентов Livewire антишаблоном или чем-то, чего следует избегать, когда это возможно, из-за потенциальных последствий для производительности. В версии 3 этого не будет!

Благодаря реактивным свойствам, связанным запросам, новому $parent свойству и другим улучшениям, v3 значительно улучшает вложенность компонентов. Мы рассмотрим некоторые из этих улучшений более подробно позже в этом посте.

Улучшенная сериализация

свойств Версия 2 пыталась интеллектуально определить, какие свойства типов были на первоначальном рендеринге, чтобы регидратировать их как те же типы при последующих запросах. Однако версия 2 не поддерживала глубоко вложенную гидратацию. Если у вас есть коллекция со смешанными типами, версия 2 не будет возвращать каждый элемент коллекции к исходному типу. V3 намного умнее в этом отношении и сохраняет тип каждого элемента, чтобы он мог вернуть их к правильным типам при последующих запросах.

Пакетные запросы В версии 2, когда несколько компонентов на странице опрашивали или прослушивали одно и то же событие, Livewire отправлял отдельные запросы

для каждого компонента каждый раз, когда ему нужно было взаимодействовать с сервером. V3 намного эффективнее и объединяет все эти обновления в один запрос.

Улучшенные

значения по умолчанию Внедрение

маркера лезвия Дифференциация DOM — одна из наиболее распространенных проблем, с которыми вы можете столкнуться в версии 2. Проблема обычно вызывалась и аналогичными @if директивами Blade, вставляющими или удаляющими элементы DOM. v3 пытается обойти эти проблемы, вставляя HTML-комментарии (маркеры) там, где эти директивы Blade начинаются и заканчиваются. Ища эти маркеры, Livewire может сопоставить новые или удаленные элементы DOM с маркером, чтобы правильно разместить их в DOM.

<form wire:submit="save">
    {{-- ... --}}

    <!-- __BLOCK__ -->
    @if ($success)
        <div>Saved!</div>
    @endif
    <!-- ENDBLOCK -->

    <div>
        <button>Save</button>
    </div>
<div>

wire:model отложен по умолчанию Первоначально «живой» Livewire был действительно крутой функцией, поэтому он был сделан по умолчанию

. После дальнейших размышлений и наблюдения за реальным использованием Калеб понял, что отсрочка wire:model запросов была лучшим вариантом по умолчанию. Большинству приложений на самом деле не требуется синхронизация входных значений с сервером при каждом нажатии клавиши, поэтому версия 3 меняет поведение по умолчанию. Предыдущая wire:model.defer функциональность — это новая функция по умолчанию при использовании wire:model. wire:model.live была добавлена для замены старого поведения по умолчанию для входных данных, которые на самом деле должны быть «живыми».

{{-- Now deferred by default --}}
<input wire:model="name">

{{-- Syncs with the server on every keystroke --}}
<input wire:model.live="name">

Новые возможности

Автоматически вставляемые ресурсы

В версии 3 Livewire автоматически внедряет свои стили, сценарии и Alpine. Больше нет необходимости добавлять <livewire:styles /> или <livewire:scripts /> загружать Alpine в свои проекты!

Новое пространство имен по умолчанию По умолчанию версия 3 использует пространство

имен (и app/Livewire каталог) вместо App\Livewire App\Http\Livewire now. Существует параметр конфигурации, позволяющий сохранить старое пространство имен, если вы предпочитаете это.

Реактивные свойства Придя из интерфейсных фреймворков, таких как React и Vue, некоторые пользователи Livewire автоматически предполагали, что свойства

, которые они передали вложенным компонентам, будут реагировать на изменения в родительском элементе. Из-за некоторых ограничений в версии 2 это было невозможно. Нам приходилось полагаться на события или другие обходные пути для синхронизации вложенных компонентов. В версии 3 добавлена поддержка «реактивных» реквизитов. Это так же просто, как добавить #[Reactive] атрибут PHP к свойству в классе компонента.

<?php
// ...
use Livewire\Attributes\Reactive; 

class InvoiceItem extends Component
{
    #[Reactive] 
    public $item;
}

Объекты формы Объекты

Объекты формы Объекты are a new concept that can help keep component classes clean by abstracting away some of the form-specific code. You may want to put a component's form properties, validation, saving functionality, and more on form objects.

Вот небольшой пример, но я бы порекомендовал прочитать документацию для получения полного списка функций!

<?php
namespace App\Livewire\Forms;

use Livewire\Form;

class UserForm extends Form
{
    #[Rule('required')]
    public $name = '';

    #[Rule(['required', 'email'])]
    public $email = '';
}
<?php
namespace App\Livewire;

use Livewire\Component;
use App\Models\Post;
use App\Livewire\Forms\UserForm;

class UpdateProfile extends Component
{
    public UserForm $form;

    public function save()
    {
        auth()->user()->update(
            $this->form->all()
        );
        return $this->redirect('/profile');
    }
    public function render()
    {
        return view('livewire.update-profile');
    }
}
<form wire:submit="save">
    <input type="text" wire:model="form.name">
    <div>
        @error('form.name')
            <span class="error">{{ $message }}</span>
        @enderror
    </div>

    <input type="email" wire:model="form.email">
    <div>
        @error('form.email')
            <span class="error">{{ $message }}</span>
        @enderror
    </div>

    <button type="submit">Save</button>
</form>

wire:navigate (Режим SPA)

Еще одним нововведением является wire:navigate. При использовании полностраничных компонентов Livewire теперь вы можете добавить атрибут wire:navigate к своим ссылкам, чтобы обеспечить SPA-подобную работу. Вместо того, чтобы загружать всю страницу, Livewire добавит индикатор загрузки в верхнюю часть страницы, извлечет содержимое новой страницы в фоновом режиме, а затем интеллектуально заменит HTML на странице. Эта функция также поддерживает предварительную выборку и перенаправления, а также позволяет сохранять элементы.

<a href="/profile" wire:navigate>Profile</a>

@persist

С добавлением wire:navigate, теперь у вас могут быть «сохраненные» элементы, которые не перезагружаются при навигации по разным страницам. Эта функция будет удобна для таких вариантов использования, как аудиоплееры, в которых вы хотите продолжать воспроизведение звука, пока ваши пользователи щелкают разные страницы.

Чтобы использовать эту функцию, оберните элемент, который вы хотите сохранить, в директиву@persist:

@persist('player')
    <audio src="{{ $episode->file }}" controls></audio>
@endpersist

Отложенные компоненты Livewire теперь поддерживает отложенные компоненты

. Иногда у вас есть компонент, который может замедлить начальную загрузку страницы или изначально скрыт внутри модального окна, которое вы хотите лениво загрузить, чтобы начальная загрузка страницы была быстрой.

Чтобы отложить загрузку компонента, добавьте атрибут к компоненту lazy в колонке.

<livewire:your-component lazy />

Livewire пропустит рендеринг этого компонента при начальной загрузке страницы. Как только все остальное содержимое будет загружено, будет отправлен сетевой запрос для полного рендеринга компонента, и компонент будет вставлен в DOM.

$parent Свойство

Для связи с «родительскими» компонентами в предыдущих версиях Livewire приходилось использовать события и прослушиватели. В версии 3 появилось новое $parent свойство, которое можно использовать для вызова методов родительских компонентов непосредственно из дочерних компонентов.

<div>
    <span>{{ $item->name }}</span>

    <button wire:click="$parent.remove({{ $item->id }})">Remove</button>
</div>

Гибридные методы/оценка JS из бэкенда v3 теперь позволяет писать методы JavaScript в ваших бэкенд-компонентах

. Добавив #[Js] атрибут к методу компонента, вы можете написать код JavaScript в виде строки, и Livewire предоставит этот метод вашему внешнему интерфейсу. При вызове через wire:clickJavaScript будет выполняться на внешнем интерфейсе без отправки сетевых запросов обратно на сервер.

<?php
// ...
use Livewire\Attributes\Js;

class UsersTable extends Component
{
    public $filters = [];

    #[Js]
    public function reset()
    {
        return <<<'JS'
            $wire.filters = [];
        JS;
    }
    // ...
}
<div>
    <div>
        <input wire:model.live="filters.active" type="checkbox">
        <label>Only active</label>
    </div>

    <button wire:click="reset">Reset Filters</button>

    @foreach ($users as $user)
        {{-- ... --}}
    @endforeach
</div>

Иногда полезно выполнять небольшие фрагменты JavaScript из ваших внутренних методов. v3 позволяет это сделать с помощью метода$this->js(). Просто вызовите метод и передайте строку JavaScript, и Livewire выполнит ее на внешнем интерфейсе при следующем рендеринге.

public function save()
{
    // ...

    $this->js("alert('You just executed JS from the backend!')");
}

Использование

атрибутов PHP Атрибуты PHP являются относительно новой и мощной функцией PHP, и Livewire v3 активно использует их для новых и существующих функций.

#[Url]

Новый #[Url] атрибут заменяет $query свойство из версии 2. Добавьте #[Url] выше любое свойство в вашем компоненте, и оно будет отслеживаться в строке запроса.

<?php
// ...
use Livewire\Attributes\Url;

class UsersTable extends Component
{
    #[Url]
    public $filters = [];

    // ...
}

#[On]

Новый #[On] атрибут заменяет $listeners свойство из версии 2. Добавьте #[On('some-event')] выше метод в свой компонент, и он будет выполняться всякий раз, когда это событие отправляется. и Атрибуты new #[Layout] и позволяют задать вид макета и

<?php
// ...
use Livewire\Attributes\Url;

class UsersTable extends Component
{
    // ...

    #[On('filters-reset')]
    public function resetFilters()
    {
        // ...
    }
}

#[Title]#[Title] заголовок для полностраничных компонентов.

#[Layout] Они могут быть добавлены к методу render компонента или к самому классу.

#[Layout('layouts.app')]
public function render()
{
    return view('livewire.create-post');
}

#[Computed]

Заменив синтаксис getSomeProperty v2 для вычисляемых свойств, мы получим атрибут.#[Computed] Он функционирует так же, как и старый синтаксис, но имеет некоторые новые, действительно мощные дополнения.

В версии 2 вычисляемые свойства можно было кэшировать только во время одного запроса. В версии 3 можно кэшировать свойство в нескольких запросах и даже в компонентах. Это упростит кэширование дорогостоящих запросов к базе данных!

use Livewire\Attributes\Computed;

// Cache across requests
#[Computed(persist: true)]
public function user()
{
    return User::findOrFail($this->userId);
}
// Cache across all instances of this component
#[Computed(cache: true)]
public function user()
{
    return User::findOrFail($this->userId);
}

#[Rule]

Новый #[Rule] атрибут заменяет $rules свойство и rules метод из версии 2. Добавьте #[Rule(['required', 'max:150'])] к свойству компонента, чтобы сообщить Livewire, как это свойство должно быть проверено.

<?php
// ...
use Livewire\Attributes\Rule; 

class InvoiceItem extends Component
{
    #[Rule(['required', 'max:120'])] 
    public $itemName;

    // ...
}

#[Locked]

Новый #[Locked] атрибут позволяет запретить пользователю обновлять свойство из веб-интерфейса. Вы можете использовать это в качестве меры безопасности для свойств, которые пользователи не должны иметь возможности изменять.

<?php
// ...
use Livewire\Attributes\Locked; 

class InvoiceItem extends Component
{
    #[Locked] 
    public $id;

    // ...
}

Обновление

Процесс обновления для большинства приложений будет довольно быстрым. В бета-версию включена livewire:upgrade команда artisan, которая поможет с некоторыми из наиболее утомительных изменений, после чего вы можете следовать руководству по обновлению , чтобы убедиться, что все обновлено.

Если вы предпочитаете оставить обновление экспертам Livewire, мы с Калебом предлагаем услугу, которая поможет вам начать процесс обновления. Вы можете проверить это здесь.

Новый дизайн веб-сайта и домен

В дополнение ко всем новым функциям и улучшениям, сайт документации Livewire был полностью переработан, перестроен и переписан!

Новая документация гораздо более подробная, чем документация v2. Они подробно описывают каждую функцию и подробно рассказывают о том, как Livewire справляется с гидратацией, морфингом и вложенными компонентами под капотом. Я настоятельно рекомендую прочитать весь сайт, так как у вас есть время. Это мастер-класс по созданию приложений Livewire v3!

Еще одно важное объявление заключается в том, что сайт документации перемещается в livewire.laravel.com. Иди туда и проверь это!


Это был длинный пост, но было так много новых функций, о которых нужно было рассказать! Я надеюсь, что вы скоро попробуете v3 и не стесняйтесь обращаться с отзывами об улучшениях.

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