Перейти к содержанию

Директива wire:model⚓︎

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

Вот простой пример использования wire:model для привязки свойств $title и $content к элементам формы в компоненте «Создание поста»:

<?php

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>Заголовок</span>

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

    <label>
        <span>Содержание</span>

        <textarea wire:model="content"></textarea>
    </label>

    <button type="submit">Сохранить</button>
</form>

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

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

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

Настройка частоты обновлений⚓︎

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

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

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

Живое обновление⚓︎

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

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

Настройка задержки⚓︎

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

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

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

Обновление по событию «blur»⚓︎

Модификатор .blur откладывает синхронизацию до тех пор, пока пользователь не кликнет за пределы поля ввода (не потеряет фокус):

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

Чтобы также отправить сетевой запрос при потере фокуса, добавьте .live:

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

Обновление по событию «change»⚓︎

Модификатор .change запускается по событию change, что полезно для элементов select:

<select wire:model.change="state">...</select>

<!-- С сетевым запросом -->
<select wire:model.change.live="state">...</select>

Обновление по клавише «enter»⚓︎

Модификатор .enter синхронизируется при нажатии пользователем клавиши Enter:

<input type="text" wire:model.enter="search">

<!-- С сетевым запросом -->
<input type="text" wire:model.enter.live="search">

Поля ввода⚓︎

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

Вот подробный список различных типов элементов ввода и способы их использования в контексте Livewire.

Текстовые поля⚓︎

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

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

Textarea⚓︎

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

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

Если значение «content» инициализируется строкой, Livewire заполнит textarea этим значением — нет необходимости делать что-то подобное:

<!-- Внимание: Этот фрагмент демонстрирует, как НЕ НУЖНО делать... -->

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

Флажки⚓︎

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

Одиночный флажок⚓︎

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

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

Теперь, когда значение $receiveUpdates равно false, флажок будет снят. Конечно, когда значение равно true, флажок будет установлен.

Несколько флажков⚓︎

Теперь, допустим, в дополнение к возможности пользователя решить получать обновления, у вас есть свойство массива в вашем классе под названием $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"]

Радиокнопки⚓︎

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

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

Выпадающие списки⚓︎

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

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

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

<select wire:model="state">
    <option value="AL">Алабама</option>
    <option value="AK">Аляска</option>
    <option value="AZ">Аризона</option>
    ...
</select>

Когда конкретный штат выбран, например, «Аляска», свойство $state на компоненте будет установлено в AK. Если вы предпочитаете, чтобы значение устанавливалось в «Аляска» вместо «AK», вы можете полностью убрать атрибут value="" из элемента <option>.

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

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

Если у вас нет конкретной опции, выбранной по умолчанию, вы можете показать отключённую опцию-заполнитель по умолчанию, например «Выберите штат»:

<select wire:model="state">
    <option disabled value="">Выберите штат...</option>

    @foreach (\App\Models\State::all() as $state)
        <option value="{{ $state->id }}">{{ $state->label }}</option>
    @endforeach
</select>

Как видите, нет атрибута «placeholder» для меню выбора, как для текстовых полей. Вместо этого вы должны добавить отключённый элемент опции в качестве первой опции в списке.

Зависимые выпадающие списки⚓︎

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

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

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

<!-- Меню выбора штатов... -->
<select wire:model.live="selectedState">
    @foreach (State::all() as $state)
        <option value="{{ $state->id }}">{{ $state->label }}</option>
    @endforeach
</select>

<!-- Зависимое меню выбора городов... -->
<select wire:model.live="selectedCity" wire:key="{{ $selectedState }}">
    @foreach (City::whereStateId($selectedState->id)->get() as $city)
        <option value="{{ $city->id }}">{{ $city->label }}</option>
    @endforeach
</select>

Единственная нестандартная вещь здесь — это wire:key, добавленный ко второму списку выбора. Это гарантирует, что при изменении штата значение «selectedCity» будет сброшено правильно.

Множественный выбор⚓︎

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

<select wire:model="states" multiple>
    <option value="AL">Алабама</option>
    <option value="AK">Аляска</option>
    <option value="AZ">Аризона</option>
    ...
</select>

Распространение событий⚓︎

По умолчанию wire:model прослушивает только события input/change, которые исходят непосредственно от самого элемента, а не события, которые всплывают от дочерних элементов. Это предотвращает неожиданное поведение при использовании wire:model на контейнерных элементах, таких как модальные окна или аккордеоны, которые содержат другие поля формы.

Например, если у вас есть модальное окно с wire:model="showModal" и поле ввода внутри него, очистка этого поля случайно не закроет модальное окно, всплывая событие change.

Прослушивание дочерних событий⚓︎

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

<div wire:model.deep="value">
    <input type="text"> <!-- Изменения здесь обновят $value -->
</div>

Используйте .deep с осторожностью

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

Доступ к вложенным свойствам⚓︎

wire:model поддерживает точечную нотацию для привязки к вложенным свойствам, элементам массивов и полям объектов форм:

<input type="text" wire:model="address.city">

<input type="text" wire:model="items.0.name">

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

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

<input type="text" wire:model="address['city']">

<input type="text" wire:model="items[0].name">

Обе нотации эквивалентны — address['city'] разрешает тот же путь, что и address.city. Нотации с квадратными скобками и точкой можно свободно смешивать в одном выражении.

Подробнее⚓︎

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

Смотрите также⚓︎

  • Forms — Полное руководство по созданию форм с Livewire
  • Properties — Понимание привязки данных и управления свойствами
  • Validation — Валидация привязанных свойств в реальном времени
  • File Uploads — Привязка полей загрузки файлов с помощью wire:model

Справочник⚓︎

wire:model="имяСвойства"
wire:model="property.nested"
wire:model="property['nested']"
wire:model="property[0]"

Модификаторы⚓︎

Модификатор Описание
.live Отправлять обновления на сервер
.blur Обновлять только при потере фокуса
.change Обновлять только по событию change
.enter Обновлять только по клавише Enter
.lazy Обновлять по change и отправлять сетевой запрос (совместимо с v3)
.debounce.Xms Задержка обновлений (используйте с .live)
.throttle.Xms Ограничение обновлений (используйте с .live)
.number Привести значение к int на сервере
.boolean Привести значение к bool на сервере
.fill Использовать начальное значение из HTML-атрибута value
.deep Также прослушивать события от дочерних элементов
.preserve-scroll Сохранять позицию прокрутки во время обновлений