Работа с формами
При работе с формами часто требуется синхронизировать состояния элементов ввода в форме с соответствующим состоянием в JavaScript. Добавлять вручную привязки значений и обработчики событий изменения может быть обременительно:
template
<input
:value="text"
@input="event => text = event.target.value"
>Директива v-model помогает упростить указанное выше до:
template
<input v-model="text">Кроме того, v-model может быть использована на полях различных типов, элементах <textarea> и <select>. Она автоматически разворачивается на различные пары свойств и событий DOM в зависимости от элемента на котором используется:
- Элементы
<input>с текстовым типом и<textarea>используют свойствоvalueи событиеinput; - Элементы
<input type="checkbox">и<input type="radio">используют свойствоcheckedи событиеchange; - Элементы
<select>используют свойствоvalueи событиеchange.
Примечание
Директива v-model игнорирует начальное значение атрибутов value, checked или selected на любых элементах форм. Источником истины всегда считается текущее состояние JavaScript. Начальное значение нужно объявить на стороне JavaScript, используя API реактивности.
Обычное использование
Текст
template
<p>Сообщение: {{ message }}</p>
<input v-model="message" placeholder="отредактируй меня" />Сообщение:
Примечание
Для языков, которые требуют IME (китайский, японский, корейский и т.д.), можно заметить, что v-model не обновляется во время IME-композиции. Если необходимо обрабатывать и эти обновления, используйте слушатель события input и привязку к value вместо использования v-model.
Многострочный текст
template
<span>Многострочное сообщение:</span>
<p style="white-space: pre-line;">{{ message }}</p>
<textarea v-model="message" placeholder="введите несколько строчек"></textarea>Многострочное сообщение:
Внутри <textarea> ИНТЕРПОЛЯЦИЯ НЕ РАБОТАЕТ, используйте v-model.
template
<!-- НЕ БУДЕТ РАБОТАТЬ -->
<textarea>{{ text }}</textarea>
<!-- А так работает -->
<textarea v-model="text"></textarea>Чекбоксы
Один чекбокс, привязанный к булевому значению:
template
<input type="checkbox" id="checkbox" v-model="checked" />
<label for="checkbox">{{ checked }}</label>Список чекбоксов, привязанных к массиву или значениям Set:
js
const checkedNames = ref([])template
<div>Отмеченные имена: {{ checkedNames }}</div>
<input type="checkbox" id="jack" value="Jack" v-model="checkedNames" />
<label for="jack">Jack</label>
<input type="checkbox" id="john" value="John" v-model="checkedNames" />
<label for="john">John</label>
<input type="checkbox" id="mike" value="Mike" v-model="checkedNames" />
<label for="mike">Mike</label>Отмеченные имена: []
В этом случае массив checkedNames всегда будет содержать значения выбранных чекбоксов.
Радиокнопки
template
<div>Выбрано: {{ picked }}</div>
<input type="radio" id="one" value="Один" v-model="picked" />
<label for="one">Один</label>
<input type="radio" id="two" value="Два" v-model="picked" />
<label for="two">Два</label>Выбрано:
Выпадающие списки
Выбор одного варианта из списка:
template
<div>Выбрано: {{ selected }}</div>
<select v-model="selected">
<option disabled value="">Выберите один из вариантов</option>
<option>А</option>
<option>Б</option>
<option>В</option>
</select>Выбрано:
Примечание
Если начальное значение выражения v-model не соответствует ни одному из вариантов списка, элемент <select> будет отображаться в «невыбранном» состоянии. В iOS это приведёт к тому, что пользователь не сможет выбрать первый элемент, потому что iOS не сгенерирует событие change в этом случае. Поэтому рекомендуется добавлять отключённый disabled-вариант выбора с пустым значением value, как показано в примере выше.
Выбор нескольких вариантов из списка (с привязкой к массиву):
template
<div>Выбраны: {{ selected }}</div>
<select v-model="selected" multiple>
<option>А</option>
<option>Б</option>
<option>В</option>
</select>Выбраны: []
Динамическое отображение списка опций с помощью v-for:
js
const selected = ref('A')
const options = ref([
{ text: 'Один', value: 'A' },
{ text: 'Два', value: 'B' },
{ text: 'Три', value: 'C' }
])template
<div>Selected: {{ selected }}</div>
<select v-model="selected">
<option v-for="option in options" :value="option.value">
{{ option.text }}
</option>
</select>Selected: A
Привязка значений
Для радиокнопок и выпадающих списков в качестве привязываемых значений v-model обычно будут статические строки (или булевые значения для чекбокса):
template
<!-- `picked` будет строкой "a" при выборе -->
<input type="radio" v-model="picked" value="a" />
<!-- `toggle` может принимать значение true или false -->
<input type="checkbox" v-model="toggle" />
<!-- `selected` будет строкой "abc" при выборе первого пункта -->
<select v-model="selected">
<option value="abc">ABC</option>
</select>Но иногда может потребоваться привязать значение к динамическому свойству текущего активного экземпляра. Для этого можно использовать v-bind. Кроме того, использование v-bind позволяет привязать значение поля с нестроковыми значениями.
Чекбокс
template
<input
type="checkbox"
v-model="toggle"
true-value="да"
false-value="нет" />Атрибуты true-value и false-value — специальные атрибуты Vue, которые работают только в связке с v-model. Здесь значение свойства toggle будет установлено в 'да', когда чекбокс выбран, и в 'нет' когда сброшен. Также можно привязать их к динамическим значением с помощью v-bind:
template
<input
type="checkbox"
v-model="toggle"
:true-value="dynamicTrueValue"
:false-value="dynamicFalseValue" />Совет
Атрибуты true-value и false-value не влияют на атрибут value элемента input, потому что браузеры пропускают невыбранные чекбоксы при отправке форм. Чтобы гарантировать отправку одного из двух значений с формой (например, «да» или «нет») используйте радиокнопки.
Радиокнопки
template
<input type="radio" v-model="pick" :value="first" />
<input type="radio" v-model="pick" :value="second" />Значение pick будет установлено в first при выборе первой радиокнопки, и в значение second при выборе второй.
Выпадающие списки
template
<select v-model="selected">
<!-- инлайновый объект с данными -->
<option :value="{ number: 123 }">123</option>
</select>Директива v-model поддерживает привязку и нестроковых значений! В примере выше, когда опция выбрана, значение selected будет объектом { number: 123 }.
Модификаторы
.lazy
По умолчанию v-model синхронизирует поле ввода с данными по событию input (кроме вышеупомянутых исключений для композиции IME). Можно воспользоваться модификатором lazy, чтобы синхронизация происходила по событию change:
template
<!-- синхронизация после события "change" вместо "input" -->
<input v-model.lazy="msg" />.number
Для автоматического приведения введённого пользователем к числу можно добавить модификатор number:
template
<input v-model.number="age" />Если значение не получится привести к числу с помощью parseFloat(), то будет возвращено исходное значение. В частности, если поле ввода пустое (например, после того, как пользователь очистил поле ввода), возвращается пустая строка. Это поведение отличается от свойства DOM valueAsNumber.
Модификатор number автоматически применяется к полям type="number".
.trim
Если необходимо автоматически удалять пробельные символы в начале и в конце строки, можно добавить модификатор trim:
template
<input v-model.trim="msg" />Использование v-model с компонентами
Если ещё не знакомы с компонентами Vue, пока просто пропустите эту секцию.
Встроенные в HTML элементы ввода не всегда соответствуют всем потребностям. К счастью, компоненты Vue позволяют создавать собственные аналоги с полностью настраиваемым поведением. Эти элементы могут работать с директивой v-model! Подробнее в разделе использования компонентов вместе с v-model.