wire:model

Livewire упрощает привязку значения свойства компонента к полям формы с помощью wire:model.

Вот простой пример использования wire:model для привязки свойств $title и $content к полям формы в компоненте "Create Post":

use Livewire\Component;
use App\Models\Post;
 
class CreatePost extends Component
{
public $title = '';
 
public $content = '';
 
public function save()
{
$post = Post::create([
'title' => $this->title
'content' => $this->content
]);
 
// ...
}
}
<form wire:submit="save">
<label>
<span>Title</span>
 
<input type="text" wire:model="title">
</label>
 
<label>
<span>Content</span>
 
<textarea wire:model="content"></textarea>
</label>
 
<button type="submit">Save</button>
</form>

Поскольку оба поля ввода используют wire:model, их значения будут синхронизированы со свойствами сервера при нажатии кнопки "Save".

"Почему мой компонент не обновляется в реальном времени при вводе?"

Если вы попробовали это в браузере и не понимаете, почему заголовок не обновляется автоматически, то это потому, что Livewire обновляет компонент только при отправке "действия" — например, при нажатии кнопки отправки, а не при вводе текста в поле. Это снижает количество сетевых запросов и улучшает производительность. Чтобы включить обновление в реальном времени во время ввода, используйте wire:model.live. Подробнее о привязке данных.

1. Настройка времени обновления

По умолчанию Livewire отправляет сетевой запрос только при выполнении действия (например, при использовании wire:click или wire:submit), НО не при обновлении поля ввода с wire:model.

Это значительно повышает производительность Livewire за счет сокращения сетевых запросов и обеспечивает более плавный пользовательский опыт.

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

1.1. Обновление в реальном времени

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

<input type="text" wire:model.live="title">

1.1.1. Настройка задержки

По умолчанию при использовании wire:model.live Livewire добавляет задержку в 150 миллисекунд перед обновлением сервера. Это означает, что если пользователь непрерывно вводит текст, Livewire подождет, пока он не перестанет печатать на 150 миллисекунд, прежде чем отправить запрос.

Вы можете настроить это время, добавив .debounce.Xms к полю ввода. Вот пример изменения задержки на 250 миллисекунд:

<input type="text" wire:model.live.debounce.250ms="title">

1.2. Обновление при событии "blur"

При добавлении модификатора .blur, Livewire будет отправлять сетевые запросы с обновлениями свойств только тогда, когда пользователь убирает фокус с поля ввода (кликая вне его) или переходит к следующему полю с помощью клавиши Tab.

Добавление модификатора .blur полезно в сценариях, когда вы хотите обновлять сервер чаще, но не при каждом нажатии клавиши. Например, .blur часто используют для валидации в реальном времени.

<input type="text" wire:model.blur="title">

1.3. Обновление при событии "change"

Иногда поведение .blur может не соответствовать вашим ожиданиям, и вместо него лучше использовать .change.

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

<select wire:model.change="title">
<!-- ... -->
</select>

Любые изменения, внесённые в текстовое поле, будут автоматически синхронизированы со свойством $title в вашем компоненте Livewire.

2. Все доступные модификаторы

Модификатор Описание
.live Отправляет обновления по мере ввода пользователем
.blur Отправляет обновления только при событии blur
.change Отправляет обновления только при событии change
.lazy Синоним для .change
.debounce.[?]ms Откладывает отправку обновлений на заданное количество миллисекунд
.throttle.[?]ms Ограничивает частоту сетевых запросов с заданным интервалом в миллисекундах
.number Преобразует текстовое значение поля ввода в int на сервере
.boolean Преобразует текстовое значение поля ввода в bool на сервере
.fill Использует начальное значение, заданное атрибутом HTML "value" при загрузке страницы

3. Поля ввода

Livewire поддерживает большинство стандартных HTML-элементов ввода «из коробки». Это означает, что вы можете просто добавить wire:model к любому элементу ввода в браузере и легко привязать к нему свойства.

Вот полный список различных доступных типов полей ввода и то, как их использовать в контексте Livewire.

3.1. Текстовые поля

Прежде всего, текстовые поля ввода — основа большинства форм. Вот как привязать к такому полю свойство с именем "title":

<input type="text" wire:model="title">

3.2. Поля textarea

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

<textarea type="text" wire:model="content"></textarea>

Если значение "content" инициализировано строкой, Livewire автоматически заполнит поле textarea этим значением — нет необходимости делать что-то вроде следующего:

<!-- Предупреждение: Этот пример показывает, как делать НЕ нужно... -->
 
<textarea type="text" wire:model="content">{{ $content }}</textarea>

3.3. Чекбоксы

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

3.3.1. Одиночный чекбокс

В конце формы регистрации может быть чекбокс, позволяющий пользователю подписаться на получение обновлений по электронной почте. Такое свойство можно назвать $receiveUpdates. Вы можете легко привязать это значение к чекбоксу с помощью wire:model:

<input type="checkbox" wire:model="receiveUpdates">

Теперь, если значение $receiveUpdatesfalse, чекбокс будет снят. И наоборот, если значение — true, чекбокс будет установлен.

3.3.2. Множественные чекбоксы

Теперь предположим, что помимо возможности для пользователя подписаться на обновления, у вас есть массив $updateTypes в классе, позволяющий выбрать различные типы обновлений:

public $updateTypes = [];

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

<input type="checkbox" value="email" wire:model="updateTypes">
<input type="checkbox" value="sms" wire:model="updateTypes">
<input type="checkbox" value="notification" wire:model="updateTypes">

Например, если пользователь установит первые два чекбокса, но не третий, значение $updateTypes будет: ["email", "sms"]

3.4. Переключатели (radio)

Чтобы переключаться между двумя различными значениями одного свойства, можно использовать переключатели (radio):

<input type="radio" value="yes" wire:model="receiveUpdates">
<input type="radio" value="no" wire:model="receiveUpdates">

3.5. Выпадающие списки

Livewire упрощает работу с выпадающими списками <select>. При добавлении wire:model к элементу select, текущее выбранное значение будет привязано к указанному имени свойства и наоборот.

Кроме того, нет необходимости вручную добавлять атрибут selected к нужному варианту — Livewire делает это автоматически.

Ниже приведён пример выпадающего списка, заполненного статическим списком российских регионов:

<select wire:model="region">
<option value="MO">Московская область</option>
<option value="KRK">Красноярский край</option>
<option value="NSO">Новосибирская область</option>
...
</select>

Когда выбран определённый регион, например "Санкт-Петербург", свойству $region в компоненте будет присвоено значение SPB. Если вы хотите, чтобы значением было "Санкт-Петербург", а не "SPB", просто не указывайте атрибут value="" у элемента <option> вообще.

Часто вы можете динамически создавать опции выпадающего списка с помощью Blade:

<select wire:model="region">
@foreach (\App\Models\Region::all() as $region)
<option value="{{ $region->id }}">{{ $region->name }}</option>
@endforeach
</select>

Как видите, у элемента select нет атрибута "placeholder", как у текстовых полей ввода. Вместо этого необходимо добавить элемент disabled в качестве первой опции в списке.

3.6. Зависимые выпадающие списки

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

В целом это работает так, как вы ожидаете, однако есть один важный момент: необходимо добавить атрибут wire:key к изменяемому выпадающему списку, чтобы Livewire корректно обновлял его значение при смене доступных опций.

Вот пример двух выпадающих списков: один для регионов, другой для городов. Когда пользователь выбирает другой регион, список доступных городов обновляется соответствующим образом:

<!-- Выпадающий список регионов -->
<select wire:model.live="selectedRegion">
@foreach (Region::all() as $region)
<option value="{{ $region->id }}">{{ $region->name }}</option>
@endforeach
</select>
 
<!-- Выпадающий список городов, зависящий от региона -->
<select wire:model.live="selectedCity" wire:key="{{ $selectedRegion }}">
@foreach (City::whereRegionId($selectedRegion)->get() as $city)
<option value="{{ $city->id }}">{{ $city->name }}</option>
@endforeach
</select>

Как и прежде, единственное нестандартное здесь — это атрибут wire:key, добавленный ко второму выпадающему списку. Он гарантирует, что при смене региона значение "selectedCity" будет корректно сброшено.

3.7. Множественные выпадающие списки

Если вы используете выпадающий список с атрибутом "multiple", Livewire работает как ожидается. В этом примере выбранные регионы будут добавляться в массив $regions, а при снятии выделения — удаляться из него:

<select wire:model="regions" multiple>
<option value="MO">Московская область</option>
<option value="NSO">Новосибирская область</option>
<option value="KRK">Красноярский край</option>
...
</select>

4. Более глубокое погружение

Более подробную документацию по использованию wire:model в контексте HTML-форм вы можете найти на странице документации по формам Livewire.