Обзор LiveWire 3 и Volt

Приветствую всех поклонников Laravel!

Эта статья-обзор новой, уже третьей версии Livewire. Решил сделать эту статью после выпуска на youtube-канале видео обзора Livewire, который понравился аудитории. Для тех, кто больше любит видео, то оно тут:

Ну и заодно также взглянем на новинку — Volt. Думаю, многие из вас ждали этот обзор и особенно обзор Volt.

Документация

Первое отличие — документация 3 версии Livewire переехала на поддомен laravel.com. Это https://livewire.laravel.com/ и заодно обновили дизайн.

08c94b9f358dc2eb6160648a81f0c52f.png

Установка

Перейдем в документацию https://livewire.laravel.com/docs/quickstart в раздел установки.

9d6da092bf2be2c2cc8af010d2368a14.png

Установка сильно упростилась и теперь зависимости устанавливаются с помощью композера:

composer require livewire/livewire

Следующий шаг — это публикация config:

php artisan livewire:publish --config

На этом всё, друзья. Теперь в основной шаблон не нужно добавлять @livewireStyles и @livewireScripts. Livewire будет делать инъекцию этих скриптов и стилей автоматически.

187f6c7e0f1b3913768f2a5dc6de7992.png

Но если вдруг Вам такой подход не нравится, то в config можете переключить false и добавлять ассеты самостоятельно, по старинке:

'inject_assets' => false,

Прежде чем мы пойдем далее, сразу скажу о понравившемся мне моменте — теперь wire:model по умолчанию с параметром defer. И это круто, так как до этого каждый раз, объявляя wire:model, приходилось добавлять .defer. Так как апдейт на каждое изменение практически никогда не был нужен (или только в редких случаях). Но теперь для этих редких случаев уже нам потребуется определенные параметры как live, либо blur.

0ed9393306f1f224bda910bd833f743d.png

Wire: Navigate

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

7770f1b2ba53e3c341644bf6dee1ae65.png

Итак, следующее на что стоит обратить внимание в Livewire 3 — это новая фича wire:navigate, мы можем ставить этот параметр на ссылке и у нас будет переход по страницам без перезагрузки:

4337a93f40ae289a35acb2c6e4dcfdf1.png

На самом деле ничего сверхъестественного нет, попытка эмуляции single page application. Как видим у меня на логотипе стоит wire:navigate:

e803931825ffd82cfe0f3eca36410c86.png

Если мы с вами по нему нажмем, то у нас перезагрузки не будет, но при этом придет HTML и основная страница заменится. Есть еще определенный интересный модификатор — называется он wire:navigate.hover:

8382c7160d2593b8334fd3e862eb51b3.png

В этом случае у нас с вами HTML-содержимое страницы придет без клика, а просто при наведении.

Forms

Далее важное изменение — это Forms (формы). Классы с формами и все что касается форм теперь вынесено в отдельный слой.

abf0d7da990619fd9a7eb92ca18410af.png

У некоторых возникли вопросы из-за того что старый подход с Model binding теперь не подходит. Давайте взглянем на Upgrade Guide и перейдем в секцию Eloquent model binding и ранее в Livewire компоненте нам было достаточно указать свойства и сделать type hint модели и далее черезwire:model, через точку, обращаться к полям этой модели.

838169ca9e5e81d558ddc4114eba3032.png

Теперь так работать не будет. Так как эту логику необходимо выносить Form Objects, о которых мы сейчас с вами поговорим. Но, если вы хотите работать по старинке, то в конфиге вы можете переключить флаг

'legacy_model_binding' => true,

и старый подход будет работать. Но я не рекомендую вам его использовать и предлагаю переходить на новую концепцию. Рано или поздно этот legacy подход отключат.

Вернемся к формам.

ae3972fd18370a69b8a24f449b05a8a9.png

Попробуем создать форму, используя artisan команду из документации.

php artisan livewire:form UserForm

И давайте также создадим компонент, где будем с вами эту форму юзать:

f3169b4fabaad94935a52df7e94216b3.png

Давайте откроем созданный компонент. Пока что пустой:

0d75292f25b378cd481d46bb4aeb84c6.png

Чтобы нам не тратить время на Blade, скопируем код формы из документации:

06c74ad0f244c5c6fa7c9a94ec678372.png

Вставляем в наш user.blade.php:

8983d699364519cf1a5d5b3f30286cc9.png

Новая особенность Livewire 3 — у формы не нужно по умолчанию указывать prevent, это будет по дефолту (так же как с wire:model — теперь не нужно по умолчанию указывать defer).

Как видим, в данном случае ничего у нас не изменилось. Только появилась определенная форма, с которой мы сейчас будем играться. Давайте оживим немного форму и в коде который мы скопировали из документации изменим form.title на form.name и form.content на form.email:

7d5c69683281afa5f5715dff34d7eb65.png

Далее, друзья, давайте смотреть на изменения. Во-первых livewire компоненты и форма теперь у нас располагаются в директории app, а не в http.

da9ef87d71f91fb02ebe5623c2dc313b.png

Формы в директории Forms, а компоненты соответственно в директории Livewire. Вот наш компонент User:

897f07ba3cce70d9935e191a168851d5.png

Как мы бы действовали с вами ранее, когда еще никаких форм не было? Верно, мы бы прямо здесь (в User.php) с вами создавали свойства. Если бы использовали Legacy подход, то сделали бы type hint c моделью и все было бы хорошо.

19425fdd8b6469631f90e2604d93c54b.png

Но давайте сделаем как положено, на отдельных свойствах — $name и $email:

e000c9906225a62602e76d15d08ed914.png

В старой версии Livewire мы в User.php сделали бы метод Save, затем добавили валидацию и указали бы правила. После этого — создаем пользователя (User::create), передав ему name и email:

b7ba6fad441e1d8b11c69a157533fe7f.png

Но, друзья, с приходом форм мы просто переносим эту логику и ответственность на сами формы давайте это сделаем и перенесем часть кода в наш UserForm.php:

01ec7d8d3b4ddd0fab2c6ace9db6b621.png

соответственно validate из User.php так же уберем:

bff65c14a98f2d2ef984763d781fcf81.png

В самой форме мы можем использовать как и по старинке наши правила — rules:

739ae9fbc09c65df12a4d05302c1763d.png

В целом, форма готова. Далее мы просто объявляем публичное свойство public UserForm $form, а в методе save() указываем $this->form->validate :

996990b971243a4ef33793c3fe85ce4e.png

Но мы можем сделать еще лучше и вынесем логику в форму:

03bd0b28712ed9a387d56713596dd6a6.png

А в самом компоненте у нас будет $this->form->storе():

7426bd965498f231b4e45deb475c6c5e.png

Давайте выведем компонент в app.blade.php, чтобы было на что посмотреть:

2c214d005425a9a656ebf5583cdb020b.png

Вернемся на главную страницу, видим, что у нас образовалась форма

b9c84d77ed575ac31da78649835dc472.png

Нажмем Save и видим, что у нас срабатывает валидация!

2e733b52a2bd14608ecc59a66969dad3.png

Мы вынесли логику в форму и у нас все работает как положено.Чтобы форма выглядела по приятнее навел немного красоты:

e36b425c198e14170f5ff9408433e579.png

Следующий вопрос — это как биндить модель в эту форму? Раньше мы просто биндели в компонент, делали type hint определенного свойства и далее через точку делали wire:model уже внутри компонента.

C формой дела обстоят немного иначе — это частый вопрос при переходе на третью версию. Давайте его с Вами рассмотрим. Откроем User.php и добавим по старинке метод mount(). Укажем, что у нас обязательный параметр модель User (\App\Models\User $user).

Давайте в форме сделаем метод setUser(User $user) и внутри наполним данными name и email для наглядности:

0f771663cc719f89295e97bc9eeb4472.png

А далее нам нужно ее установить (засетить) форму, то есть сделать $this->form->setUser ($user)

4d2be87bdd0860aa2f2e9fc10171f182.png

Далее открываем app.blade.php (там, где мы рендерим компонент) и добавляем livewire:user:

86982e4241d3020fcbcbc18cb7fed595.png

Давайте посмотрим, что у нас из этого получилось. Видим что у нас бинд срабатывает и данные подставляются:

fb8b889ea0e503cc6e6061da7cf10f1b.png

Теперь если очистим нажмем save, видим, что и валидация у нас работает:

0c33eb5fc6258ec1e3b946886145d458.png

PHP attributes

Дальше вопрос валидации. Здесь есть некоторые изменения — старый подход через методы rules(),  messages() работает, но также для нашего удобства добавили PHP атрибуты. Да Livewire просто пестрит PHP атрибутами, они практически везде и сейчас постепенно мы их с вами будем осваивать.

Давайте уберем пока что метод rules() из UserForm.php и далее с помощью атрибута Rule из Livewire будем добавлять необходимые нам правила — required, string и min со значением 3. То же самое продублируем и на e-mail:

11a061e669861277fdae0550b05c25b4.png

Вернемся в браузер, обновляемся, попробуем очистить поля, нажмем save и видим что у нас все так же работает только теперь через PHP атрибуты.

bdf6a717c7b4a257dfcf70dcfdce4711.png

Добавлять атрибуты можно другим способом, Вы можете перейти в раздел валидация и более углубленно взглянуть на те возможности, которые дают нам PHP атрибуты. Есть дополнительные свойства, прямо в атрибуте можно указать и сообщения валидации, а также переводить сообщения или нет, можно указывать в виде массива, добавлять туда классы. Подход через PHP attributes присутствует, и если он вам больше нравится, то обязательно используйте. Если нет, то можете пользоваться старым подходом через rules(): array:

10a335b0ec63d69e8c04f7e4896bb59c.png

Кстати, большинство новичков ищут в документации что-либо о Form Requests. У нас есть форма и хочется в ней применять стандартные Form Requests, но если вы пройдетесь по документации Livewire, то вы не увидите ни одного слова о Form Requests. Но если вдруг вы хотите их использовать, то можете их интегрировать прямо в метод rules().

Давайте создадим какой-либо Form Requests, так как в проекте который используется для примера их нет.

79b9db67132e05c50f8c4d9a3d3d740d.png

И если бы я хотел интегрировать сюда в Form Requests, я бы сделал следующее и в целом это рабочий подход для решения.

020d26245dd7a12aa0af653c25ad3fe2.png

Друзья, раз уж мы с вами затронули тему PHP атрибутов в Livewire, то давайте ее продолжим и посмотрим еще на несколько таких атрибутов. Для этого переместимся в компонент для главной страницы (Home.php), здесь full page компоненты и поэтому я прямо в компоненте могу с помощью PHP атрибутов задавать title страницы, менять layout. Как это делается? Например, у метода render() я могу добавить атрибут title и указать что-либо (Hello):

39c358aa88fcb50aa9cb4384485b90d6.png

Давайте вернемся назад, обновимся и видим, что заголовок поменялся на тот который я указал:

c01485d91dc53b1d80c213093d0b91dc.png

Тоже самое можно было бы сделать не у метода render(), а у класса Home и все так же будет работать:

27f3d1933134353fb333458061600506.png

И в таком же стиле я могу менять layout, используя атрибут Layout где указываем его расположение и это будет работать.

bd0fa2492b4a7757e8854300b0406ea7.png

Давайте сделаем ошибку, чтобы убедиться что действительно работает — укажем components.layouts.app2 — такого layout уже нет и получаем соответствующее уведомление об ошибке:

d622fea6114c69d3ec82998fadfba034.png

Следующий интересный атрибут — Locked, давайте посмотрим как он выглядит и как он работает. На определенное свойство мы можем его с вами повесить и далее в клиентской части уже не сможем его изменять.Давайте попробуем и повесим его на поле для ввод имени пользователя, попытаемся изменить (что-либо ввести в поле) нажимаю Save и у меня появляется исключение — что Locked Property мы менять с вами не можем.

d6e2acede237a09656cd4cb6c65456a8.png

События

Друзья, следующее что мы с вами рассмотрим — это события (events) и как по мне с атрибутами это супер интересный подход. Давайте взглянем как это работает? К примеру во время сохранения (User.php) мы с вами будем вызывать событие, пусть это будет form-store. Закомментируем 22 строку и добавим метод onFormStore() в котором для наглядности и простоты сделаем Dump and Die (dd). Теперь укажем через атрибут On на какое событие будет вызываться этот метод, соответственно form-store. То есть в методе save() события дергаем, а в onFormStore() указываем какое (событие) будет при этом вызываться.

И таких listener может быть несколько.

f24538c6a040980550d79d7bf9df6f8f.png

Проверим в браузере, нажимаем на save и видим что dump & die срабатывает:

ba7af4c12f5c6cd2e605057880c8b3fe.png

Мы даже с вами можем взять метод onFormStore() из User.php и вынести его в какой-то другой компонент, например разместим на главной странице Home.php. Проверим в браузере — событие снова вызовется.

Также интересный атрибут, когда мы дергаем какой-либо метод из Blade компонента, то у нас происходит ReRender. Приходят данные и компонент рендерится по-новому. Если на определенные методы такое поведение нам необходимо исключить, то мы можем добавить атрибут Renderless и в таком случае, когда мы будем дергать этот метод, компонент перерисовываться не будет:

5f9816948f65c60a200defc86ca4deef.png

Вычисляемые свойства

Следующий интересный раздел в Livewire 3 — это computed properties, вычисляемые свойства. Необходимы они нам для контроля над производительностью. Если мы вешаем атрибут Computed над каким-то методом, то он нам уже будет доступен через $this-> внутри этого компонента и внутри Blade-компонента. Но при этом в процессе реквеста вызываться он будет только единожды:

98584c384765c9a71f5b02d590ac5494.png

Независимо от того, что у нас здесь запрос к базе, livewire закэширует содержимое и мы при неоднократном обращении к одному и тому же методу будем всегда возвращать одно и то же значение. Давайте взглянем как это работает? Будем использовать компонент User.php, создадим свойство u() и добавим ему компонент [Computed], а в содержании укажем о возвращении рандомного юзера. И давайте пару раз задампим его. Во-первых в методе render() указанном в User.php, здесь обратите внимание свойства не создавалось, но обращение как к свойству u.

dccb1ea96177a1a89973a54d9bcc85a8.png

Во-вторых, то же самое в blade-компоненте user.blade.php. Также обращаю ваше внимание на то, что в blade-компоненте мы также вызываем через $this->:

09b8c0fabbd03f9f25d249871b5e0de1.png

Как видите в компоненте мы вызываем id пользователя и тоже самое внутри Blade шаблона. Но при этом, отправляем всего один request цикл, один запрос:

2b7d81ec5952e2cdd57611f3fca07ffd.png

Также мы можем дополнительно кэшировать, указав в computed cache:true :

bcdfebf19fa819a70baebadae2662fe6.png

Проверим. При каждом обновлении будет приходить id первого пользователя:

49503723e584b6405310c05b05c14381.png

Вложенные компоненты

Передвигаемся в более интересную тему это вложенные компоненты (nesting components). По сути полностью переписанный подход в Livewire 3 и теперь он работает намного круче и есть реактивность. Давайте взглянем на практике — создадим еще один с вами компонент, который будет у нас внутри компонента User. Давайте назовем его UserInner:

5a893957c72e110e53a3af8412e73553.png

Сразу его откроем и вызовем его в нашем компоненте user.blade.php, как раз он станет у нас вложенным и сразу давайте передадим в него форму:

cac24b04f435f9d95907907b8dc44232.png

Откроем UserInner.php и создадим метод mount():

666fc58088cfedcd3058edc68f941c9c.png

Давайте откроем view user-inner.blade.php и в ней соответственно выведем что-то из формы, например name и заодно сразу добавим Input, чтобы добавить wire:model:

a5069ade15c0dac18169a0e72a326062.png

Посмотрим в браузере что у нас при этом получается. Обновляемся, и видим, что у нас есть родительская форма и есть дочерняя:

b980b2b4bacb35693a26bb34e8ef80ef.png

И давайте заодно добавим кое-что в родительское поле. Укажем, что у нас wire:model.live — чтобы при вводе сразу менялась свойство формы:

a4a477db8d593c6d2f2cfb0d99e3b68e.png

Возвращаемся в браузер и меняем содержимое поля. Видим что у нас в родительском компоненте значение изменяется, но при этом в дочернем ничего не меняется:

3360d703f2a0972793ceb6f0eb96ef5e.png

Так работал Livewire раньше, никакой реактивности не было. У нас рендерился только родительский компонент. Давайте заодно взглянем на запросы, которые у нас отправляются. Если мы с вами будем менять содержимое родительского поля,

67ca3fb82cd26ecab9f797743ae6e1a7.png

Видим что уходит апдейт и у нас только один компонент изменяется и приходит только его HTML:

d660b2b8c534b40d0006ae6ac1e0afcf.png

Чтобы менять и дочерние, добавить реактивности которую мы ожидаем, нам нужно с вами перейти в UserInner.php и на форму повесить атрибут [Reactive]. Возвращаемся в браузер, обновляемся и теперь при вводе значений в поля формы у нас меняется и содержимое дочернего поля и его wire:model и значение:

8ba8e67f93af1b768a398c6003c029a6.png

Посмотрим в инструментах разработчика на вкладу Network, что там происходит. При вводе в родительское поле видим, что в update у нас массив с двумя компонентами — и родитель и все его дочерние:

8850c0a14ad8b9a08111097ff06349c0.png

И напоследок еще немного магии по вложенным компонентам. Нам также доступна переменная $parent с помощью которой мы можем обратиться к объекту родительского компонента. Давайте попробуем:
$parent->form->name

26828589d42037643b22ac18e8efba25.png

Смотрим в браузере — вводим значения в поле родительской формы и это же значение появляется и в дочерней. Работает!

11013858470fec88da81fdde13047503.png

Polling

Друзья, также хочу вам показать раздел polling и wire:poll который был и до этого. Многие думают, что у нас происходит живое обновление по типу веб-сокетов. Даже в документации написано технология как web-сокеты, но ничего общего с веб-сокетами это не имеет. Конечно штука интересная, но в ней нет ничего необычного. На самом деле это просто запросы по тайм-ауту, поэтому рекомендую относиться к этой директиве крайне аккуратно. Давайте добавим на компонент user-inner.blade.php wire:poll:

Посмотрим в браузере, на вкладку Network инструментов разработчика:

f9b3a2064af94782e9cdc7249a650f19.png

Как видите по тайм-ауту происходит запрос, простой запрос, никакие не веб-сокеты и в ответе мы получаем данные по компоненту. Если что-то там на сервере изменилось, то само собой придут данные. Но обратите внимание как мы сейчас спамим запросами к серверу, поэтому крайне аккуратно относитесь к этой директиве. Если у вас их будет множество, все они будут спамить, решение будет не из лучших, а под капотом нет никакой магии, простой тайм-аут:

f71005de13f5e078f453367f9f14317f.png

Lazy Components

Следующее что я хочу вам показать это крайне интересная фича, а именно Lazy компоненты — ленивые компоненты, которые сразу у нас не грузятся, а когда у нас уже пришел ответ, уже после этого отправляется запрос, не мешая нашему первому рендеру. Для этого достаточно добавить lazy:

459fef93f1c0432554494f93b4aff29c.png

Представим, у нас есть какие-то компоненты, какие-то сложные метрики с множеством запросов. Не хочется чтобы наша страница грузилась несколько секунд перед тем как отдать ее пользователю. Мы добавляем lazy, а далее переходим в компонент и вешаем на него placeholder. Это то, что у нас появится прежде чем мы запустим рендер компонента. И давайте чтобы посмотреть как это работает сделаем sleep продолжительностью 3 секунды:

bdb7dc283485ef84a67c199bd9f57a4d.png

Вернемся на в браузер и обновимся:

374abbed91d30c974a2829bb2fb513db.png

Видим, что второго компонента пока что нет, есть надпись «loading», идёт загрузка и только по прошествию указанного времени (мы указали 3 сек.), появился наш дочерний элемент:

25d77910107fde6fe6d4f982e08f9138.png

Отличная штука обязательно берем на вооружение.

LiveWire Volt

Настало время для обзора Volt. На самом деле это тот же самый Livewire, он располагается в документации Livewire и создан на его основе. Единственное его отличие, что все находится в одном blade файле. Никакого Livewire класса, Livewire класс-компонента больше нет. И сверху в теге PHP мы организуем всю backend логику, а дальше у нас идет frontend. Разработчики вдохновлялись Vue Framework.

Устанавливается Volt просто, сперва устанавливаем Livewire, затем Volt. Делается это командой volt:Install, которая добавляет сервис провайдер — VoltServiceProvider.

Внутри мы указываем где у нас располагаются Livewire компоненты, где будут располагаться страница для Folio.

0825ef51f37110901c73c631cab3602e.png

Далее, чтобы создать компонент используем команду make:volt и далее название, как make:livewire, только ключевое слово volt. Во всем остальном обязательно изначально вам нужно знать livewire, а уже после использовать Volt. Все то же самое перекочевало сюда в виде функций-хелперов. Единственное с чем может быть замешательство — это то, что входные параметры передаются при помощи функции state. Если нам необходим какой-то экшен, то вызываем его анонимной функцией.

b4d406dcd6e67f755efa0793274fec8e.png

Также нам говорят что в целом можем использовать и классы, но также сверху blade-файла, внутри. Как по мне — это выглядит крайне убого! Если на то что мы пишем логику прямо в Blade в целом в рамках Volt можно закрыть глаза на каких-то небольших компонентах, но добавлять анонимные классы, считаю что выглядит ужасно.

Окей, со state мы разобрались. Если нам необходим метод Mount, то пользуемся функцией mount() :

058ddc73669e092c82fc598066a95b9f.png

Хотим изменить layout — пользуемся функцией layout() :

501e04dc7aefd6481e9fcb2a5940acdb.png

Пользуемся функцией title для заголовка:

1b82c6cf32d825ee2ff25a8dcdeca1ca.png

Как я говорил ранее все то же самое есть и здесь. Продолжим листать документацию и видим пример использования locked() через state(). Мы использовали его ранее:

647e373d8687cc5da19ceb561eb47229.png

То же самое с reactive, то же самое с computed. Это тот же самый Livewire, просто изменился подход. Все теперь организовывается в Blade-компоненте. Можем продолжать листать документацию до бесконечности и ничего нового мы с вами здесь не увидим «сахар», «сахар», «сахар» в виде дополнительных функций, которые делают в точности все то же самое, что мы делали в стандартном Livewire классе.

Давайте все же немного поиграемся и создадим с volt-компонент counter:

e8e9f530d105895562fcabfa6a2ed332.png

Отлично, видим что Blade компонент создан и больше ничего. Вот он так выглядит по дефолту:

de8da13f72b5072dbd4274ef88ba538e.png

Дальше нам предлагается со всем этим взаимодействовать. Давайте создадим определенный state, пусть будет count и по дефолту сделаем 0. Давайте попробуем вывести. Насколько я помню необходимо использовать $this.

87ec19b4464dab9fdc672d4b9bee314f.png

Вернемся в браузер, обновимся и видим нолик, это state и то значение, которое мы здесь задаем:

fab9a3e874f15b065c26bcc4e848d1d1.png

Давайте также добавим Action. Пусть будет кнопка которая у нас будет инкрементировать этот счетчик count. Используем wire:click. Добавим инкремент, чтобы создать экшен, достаточно создать переменную которая у нас будет анонимная функция. На самом деле уже понимаю, что не очень удобно работать так как PHPStorm мне не подсказывает что в рамках $this-> контекста у нас есть count и приходится все писать самому:

f8d6361a009bd4f6726d6ee308654aaa.png

Посмотрим в браузер, попробуем нажать в область отображения счетчика и видим что счетчик у нас меняется:

e2ab97fe648b7175cf1b66044bbb9da8.png

Давайте еще немного поиграем с Volt, заодно в очередной раз разберем тему computed properties — вычисляемых свойств, так как она мне очень нравится. Давайте создадим переменную $test со значением computed(function()), далее callback и внутри мы вернем count. И давайте выведем наш test, только он у нас computed:

a11b6ebd17df47b4eb6fb950eb25bf53.png

Вернемся в браузер, нажимаем на »+», пытаемся инкрементировать. И первая переменная и вторая ведут себя абсолютно идентично:

69e0d6aa7b14ee2062106b5f5a0f79fc.png

Но давайте добавим computed метод persist, который у нас будет кэшировать (запоминать):

cd3f10941e22dc7eb075288a402ee66c.png

Вернемся в браузер. При первом заходе у нас отображается значение 00, а дальше мы с вами инкрементируем, но computed теперь никак не меняется, так как это значение у нас закэшировано и повторно ничего не происходит:

58e56f7221ee51b0917420f39721be5b.png

Давайте для наглядности изменим persist, добавив seconds и укажем чтобы он у нас хранился всего 2 секунды.

2857f1661dbe9ed6b49c96a054384c66.png

Вернемся в браузер, обновимся, инкрементируем и видим, что не каждое изменение, но раз в 2 секунды у нас приходят измененные значения:

d56eb629ecc33152c1701c196bbebe27.png

Друзья, как видите ковырять Volt мы можем с вами сколько угодно долго, но никаких отличий от Livewire, кроме подхода «все в одном blade-файле», больше нет. В целом лично мне Livewire 3 дал так называемое второе дыхание, хочется что-то на нем написать, использовать, делать ролики на мой Youtube канал, но опять-таки только в том случае если и вам интересно. Поэтому обязательно напишите в комментариях стоит ли продолжать делать уроки по Livewire?

Спасибо за уделенное внимание. Данил Щуцкий, автор проекта CutCode.

© Habrahabr.ru