# Работа с формами
# Обычное использование
Можно использовать директиву v-model
для создания двусторонней привязки данных с элементами форм: input, textarea и select. Она автоматически выбирает правильный способ обновления элемента в зависимости от его типа. Хоть v-model
и выглядит как некая магия, по сути это лишь синтаксический сахар для обновления данных при вводе пользователем, плюс небольшие доработки для некоторых граничных случаев.
Примечание
v-model
игнорирует начальное значение атрибутов value
, checked
или selected
на любых элементах форм. Источником истины всегда считаются данные текущего активного экземпляра. Начальное значение нужно объявить на стороне JavaScript, внутри опции data
компонента.
Внутренне v-model
использует разные свойства и генерирует разные события для различных элементов форм:
- элементы для ввода текста и многострочного текста используют свойство
value
и событиеinput
; - чекбоксы и радиокнопки используют свойство
checked
и событиеchange
; - выпадающие списки используют свойство
value
и событиеchange
.
Примечание
Для языков, которые требуют IME (opens new window) (китайский, японский, корейский и т.д.), можно заметить, что v-model
не обновляется во время IME-композиции. Если необходимо обрабатывать и эти обновления, используйте слушатель события input
и привязку к value
вместо использования v-model
.
# Текст
<input v-model="message" placeholder="отредактируй меня" />
<p>Сообщение: {{ message }}</p>
2
See the Pen Работа с формами: обычное использование v-model by Vue (@Vue) on CodePen.
# Многострочный текст
<span>Многострочное сообщение:</span>
<p style="white-space: pre-line;">{{ message }}</p>
<br />
<textarea v-model="message" placeholder="введите несколько строчек"></textarea>
2
3
4
See the Pen Работа с формами: многострочный текст by Vue (@Vue) on CodePen.
Интерполяция внутри textarea не работают. Используйте директиву v-model
вместо неё.
<!-- НЕ РАБОТАЕТ -->
<textarea>{{ text }}</textarea>
<!-- ok -->
<textarea v-model="text"></textarea>
2
3
4
5
# Чекбоксы
Один чекбокс, привязанный к булевому значению:
<input type="checkbox" id="checkbox" v-model="checked" />
<label for="checkbox">{{ checked }}</label>
2
See the Pen Работа с формами: чекбоксы by Vue (@Vue) on CodePen.
Список чекбоксов, привязанных к одному массиву:
<div id="v-model-multiple-checkboxes">
<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>
2
3
4
5
6
7
8
9
10
Vue.createApp({
data() {
return {
checkedNames: []
}
}
}).mount('#v-model-multiple-checkboxes')
2
3
4
5
6
7
See the Pen Работа с формами: список чекбоксов by Vue (@Vue) on CodePen.
# Радиокнопки
<div id="v-model-radiobutton">
<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>
</div>
2
3
4
5
6
7
8
9
Vue.createApp({
data() {
return {
picked: ''
}
}
}).mount('#v-model-radiobutton')
2
3
4
5
6
7
See the Pen Работа с формами: радиокнопки by Vue (@Vue) on CodePen.
# Выпадающие списки
Выбор одного варианта из списка:
<div id="v-model-select" class="demo">
<select v-model="selected">
<option disabled value="">Выберите один из вариантов</option>
<option>А</option>
<option>Б</option>
<option>В</option>
</select>
<span>Выбрано: {{ selected }}</span>
</div>
2
3
4
5
6
7
8
9
Vue.createApp({
data() {
return {
selected: ''
}
}
}).mount('#v-model-select')
2
3
4
5
6
7
See the Pen Работа с формами: выпадающие списки by Vue (@Vue) on CodePen.
Примечание
Если начальное значение выражения v-model
не соответствует ни одному из вариантов списка, элемент <select>
будет отображаться в «невыбранном» состоянии. В iOS это приведёт к тому, что пользователь не сможет выбрать первый элемент, потому что iOS не сгенерирует событие change
в этом случае. Поэтому рекомендуется добавлять отключённый disabled
-вариант выбора с пустым значением value, как показано в примере выше.
Выбор нескольких вариантов из списка (с привязкой к массиву):
<select v-model="selected" multiple>
<option>А</option>
<option>Б</option>
<option>В</option>
</select>
<br />
<span>Выбраны: {{ selected }}</span>
2
3
4
5
6
7
See the Pen Работа с формами: выпадающий список с привязкой к массиву by Vue (@Vue) on CodePen.
Динамическое отображение списка опций с помощью v-for
:
<div id="v-model-select-dynamic" class="demo">
<select v-model="selected">
<option v-for="option in options" :value="option.value">
{{ option.text }}
</option>
</select>
<span>Выбрано: {{ selected }}</span>
</div>
2
3
4
5
6
7
8
Vue.createApp({
data() {
return {
selected: 'A',
options: [
{ text: 'Один', value: 'A' },
{ text: 'Два', value: 'B' },
{ text: 'Три', value: 'C' }
]
}
}
}).mount('#v-model-select-dynamic')
2
3
4
5
6
7
8
9
10
11
12
See the Pen Работа с формами: выпадающий список с динамическими опциями by Vue (@Vue) on CodePen.
# Привязка значений
Для радиокнопок и выпадающих списков в качестве привязываемых значений 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>
2
3
4
5
6
7
8
9
10
Но иногда может потребоваться привязать значение к динамическому свойству текущего активного экземпляра. Для этого можно использовать v-bind
. Кроме того, использование v-bind
позволяет привязать значение поля с нестроковыми значениями.
# Чекбокс
<input type="checkbox" v-model="toggle" true-value="да" false-value="нет" />
// когда чекбокс выбран
vm.toggle === 'да'
// когда чекбокс сброшен
vm.toggle === 'нет'
2
3
4
5
Совет
Атрибуты true-value
и false-value
не влияют на атрибут value
элемента input, потому что браузеры пропускают невыбранные чекбоксы при отправке форм. Чтобы гарантировать отправку одного из двух значений с формой (например, «да» или «нет») используйте радиокнопки.
# Радиокнопки
<input type="radio" v-model="pick" :value="a" />
// когда выбран
vm.pick === vm.a
2
# Выпадающие списки
<select v-model="selected">
<!-- инлайновый объект с данными -->
<option :value="{ number: 123 }">123</option>
</select>
2
3
4
// когда выбран
typeof vm.selected // => 'object'
vm.selected.number // => 123
2
3
# Модификаторы
# .lazy
По умолчанию v-model
синхронизирует поле ввода с данными по событию input
(кроме вышеупомянутых исключений для событий IME). Можно указать модификатор lazy
, чтобы синхронизация происходила после события change
:
<!-- синхронизация после события "change" вместо "input" -->
<input v-model.lazy="msg" />
2
# .number
Для автоматического приведения введённого пользователем к числу можно добавить модификатор number
:
<input v-model.number="age" type="text" />
Это часто бывает полезно при использовании полей с типом text
. При указании типа поля number
— Vue автоматически станет конвертировать строковое значение в число, добавлять модификатор .number
к v-model
не потребуется. Если значение не получится привести к числу с помощью parseFloat()
, то будет возвращено исходное значение.
# .trim
Если необходимо, чтобы пробельные символы в начале и в конце строки автоматически обрезались, то можно добавить модификатор trim
для полей ввода, управляемых через v-model
:
<input v-model.trim="msg">
# Использование v-model
с компонентами
Если ещё не знакомы с компонентами Vue, пока просто пропустите эту секцию
Встроенные в HTML элементы ввода не всегда соответствуют потребностям. К счастью, компоненты Vue позволяют создавать собственные аналоги с полностью настраиваемым поведением. Эти элементы тоже могут работать с директивой v-model
!
Подробнее в разделе пользовательские элементы ввода.