Работа с формами

Типичное использование

Можно использовать директиву v-model для двунаправленного связывания данных с элементами форм input, textarea и select. Способ обновления элемента выбирается автоматически в зависимости от типа элемента. Хотя v-model и выглядит как нечто волшебное, в действительности это лишь синтаксический сахар для обновления данных в элементах ввода, с некоторыми поправками для исключительных случаев.

v-model игнорирует атрибуты value, checked или selected на любых элементах форм. Данные экземпляра Vue всегда считаются источником истины. Начальное значение необходимо объявить на стороне JavaScript, внутри опции data компонента.

В языках, требующих IME (китайский, японский, корейский и т.д.), можно заметить, что v-model не обновляется по мере IME-композиции. Если вы хотите обрабатывать и эти обновления, используйте события input.

Текст

<input v-model="message" placeholder="отредактируй меня">
<p>Введённое сообщение: {{ message }}</p>

Введённое сообщение: {{ message }}

Многострочный текст

<span>Введённое многострочное сообщение:</span>
<p style="white-space: pre-line;">{{ message }}</p>
<br>
<textarea v-model="message" placeholder="введите несколько строчек"></textarea>
Введённое многострочное сообщение:

{{ message }}


Интерполяция внутри textarea (<textarea>{{text}}</textarea>) не будет работать. Используйте вместо неё директиву v-model

Чекбоксы

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

<input type="checkbox" id="checkbox" v-model="checked">
<label for="checkbox">{{ checked }}</label>

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

<div id="example-3" class="demo">
<input type="checkbox" id="jack" value="Джек" v-model="checkedNames">
<label for="jack">Джек</label>
<input type="checkbox" id="john" value="Джон" v-model="checkedNames">
<label for="john">Джон</label>
<input type="checkbox" id="mike" value="Майк" v-model="checkedNames">
<label for="mike">Майк</label>
<br>
<span>Отмеченные имена: {{ checkedNames }}</span>
</div>
new Vue({
el: '#example-3',
data: {
checkedNames: []
}
})

Отмеченные имена: {{ checkedNames }}

Радиокнопки

<input type="radio" id="one" value="Один" v-model="picked">
<label for="one">Один</label>
<br>
<input type="radio" id="two" value="Два" v-model="picked">
<label for="two">Два</label>
<br>
<span>Выбрано: {{ picked }}</span>


Выбрано: {{ picked }}

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

Выбор одного варианта из списка:

<select v-model="selected">
<option disabled value="">Выберите один из вариантов</option>
<option>А</option>
<option>Б</option>
<option>В</option>
</select>
<span>Выбрано: {{ selected }}</span>
new Vue({
el: '...',
data: {
selected: ''
}
})
Выбрано: {{ selected }}

Если начальное значение выражения v-model не соответствует ни одному из вариантов списка, элемент <select> будет отображаться в «невыбранном» состоянии. В iOS это приведёт к тому, что пользователь не сможет выбрать первый элемент, потому что iOS не сгенерирует событие change в этом случае. Поэтому рекомендуется предоставлять отключённый вариант выбора с пустым значением value, как показано в примере выше.

Выбор нескольких вариантов из списка (с привязкой к массиву):

<select v-model="selected" multiple>
<option>А</option>
<option>Б</option>
<option>В</option>
</select>
<br>
<span>Выбрано: {{ selected }}</span>

Выбрано: {{ selected }}

Динамическое отображение списка опций с помощью v-for:

<select v-model="selected">
<option v-for="option in options" v-bind:value="option.value">
{{ option.text }}
</option>
</select>
<span>Выбрано: {{ selected }}</span>
new Vue({
el: '...',
data: {
selected: 'А',
options: [
{ text: 'Один', value: 'А' },
{ text: 'Два', value: 'Б' },
{ text: 'Три', value: 'В' }
]
}
})
Выбрано: {{ selected }}

Связывание значений

Для радиокнопок, чекбоксов и выпадающих списков в качестве v-model обычно используются статические строки (для чекбоксов — булевые значения):

<!-- `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>

Иногда необходимо связать значение с динамическим свойством экземпляра Vue. Для этого можно использовать v-bind. Кроме того, использование v-bind позволяет связывать поле ввода с нестроковыми значениями.

Чекбокс

<input
type="checkbox"
v-model="toggle"
true-value="да"
false-value="нет"
>
// если чекбокс выбран:
vm.toggle === 'да'
// если чекбокс сброшен:
vm.toggle === 'нет'

Атрибуты true-value и false-value не влияют на атрибут value тега input, потому что браузеры пропускают невыбранные чекбоксы при отправке форм. Чтобы гарантированно отправлять одно из двух значений с формой (например, «да» или «нет») используйте радиокнопки.

Радиокнопки

<input type="radio" v-model="pick" v-bind:value="a">
// если отмечено:
vm.pick === vm.a

Списки выбора

<select v-model="selected">
<!-- инлайновый объект с данными -->
<option v-bind:value="{ number: 123 }">123</option>
</select>
// когда выбрано:
typeof vm.selected // => 'object'
vm.selected.number // => 123

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

.lazy

По умолчанию v-model синхронизирует ввод с данными по событию input (за исключением вышеупомянутых событий IME). Можно указать модификатор lazy, чтобы использовать для синхронизации событие change:

<!-- синхронизируется по событию "change", а не "input" -->
<input v-model.lazy="msg" >

.number

Для автоматического приведения введённого пользователем к числу, добавьте модификатор number:

<input v-model.number="age" type="number">

Зачастую это полезно, потому что даже при указанном атрибуте type="number" значением поля ввода всегда будет строка. Если значение не удаётся распарсить с помощью parseFloat(), то возвращается оригинальное значение.

.trim

Чтобы автоматически обрезать пробелы в начале и в конце введённой строки, используйте модификатор trim:

<input v-model.trim="msg">

Использование v-model с компонентами

Если вы ещё не знакомы с компонентами Vue, пока просто пропустите эту секцию

Встроенных в HTML элементов ввода не всегда достаточно. К счастью, компоненты Vue позволяют создавать собственные аналоги с полностью настраиваемым поведением. Эти элементы тоже могут работать с директивой v-model. Подробнее в разделе пользовательские элементы ввода.