Можно использовать директиву v-model
для двунаправленнй связки данных с элементами форм input, textarea и select.
Способ обновления элемента выбирается автоматически в зависимости от типа элемента. Хотя v-model
и выглядит как нечто волшебное, в действительности это лишь синтаксический сахар для обновления данных в элементах ввода, с некоторыми поправками для исключительных случаев.
Директива v-model
игнорирует начальное значение атрибутов value
, checked
или selected
на любых элементах форм. Данные экземпляра Vue всегда считаются источником истины. Начальное значение необходимо объявить на стороне JavaScript, внутри объекта настроек data
компонента.
Внутренне v-model
использует разные свойства и генерирует разные события для различных элементов ввода:
value
и событие input
;checked
и событие change
;value
и событие change
.<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>
Список флажков, привязанных к одному массиву:
<input type="checkbox" id="ivan" value="Иван" v-model="checkedNames">
<label for="ivan">Иван</label>
<input type="checkbox" id="petr" value="Петр" v-model="checkedNames">
<label for="petr">Петр</label>
<input type="checkbox" id="tolik" value="Толик" v-model="checkedNames">
<label for="tolik">Толик</label>
<br>
<span>Отмеченные имена: {{ checkedNames }}</span>
new Vue({
el: '...',
data: {
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>
Выбор одного варианта из списка:
<select v-model="selected">
<option disabled value="">Выберите один из вариантов</option>
<option>А</option>
<option>Б</option>
<option>В</option>
</select>
<span>Выбрано: {{ selected }}</span>
new Vue({
el: '...',
data: {
selected: ''
}
})
Если начальное значение выражения v-model
не соответствует ни одному из вариантов списка, элемент <select>
будет отображаться в «невыбранном» состоянии. В iOS это приведёт к тому, что пользователь не сможет выбрать первый элемент, потому что iOS не сгенерирует событие change
в этом случае. Поэтому рекомендуется предоставлять отключённый disabled
-вариант выбора с пустым значением value, как показано в примере выше.
Выбор нескольких вариантов из списка (с привязкой к массиву):
<select v-model="selected" multiple>
<option>А</option>
<option>Б</option>
<option>В</option>
</select>
<br>
<span>Выбрано: {{ selected }}</span>
Динамическое отображение списка выбора с помощью 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: 'В' }
]
}
})
Для радиокнопок и выбиралок в качестве 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
. Можно указать изменитель lazy
, чтобы использовать для синхронизации после события change
:
<!-- синхронизируется по событию "change", а не "input" -->
<input v-model.lazy="msg">
.number
Для автоматического приведения введённого пользователем к Number, добавьте изменитель number
:
<input v-model.number="age" type="number">
Зачастую это полезно, потому что даже при указанном атрибуте type="number"
значением вводилки всегда будет строка. Если значение не удаётся разобрать с помощью parseFloat()
, то возвращается оригинальное значение.
.trim
Если необходимо, чтобы автоматически обрезались пробелы в начале и в конце строки, используйте изменитель trim
для полей ввода, обрабатываемых через v-model
:
<input v-model.trim="msg">
v-model
с компонентамиЕсли вы ещё не знакомы с компонентами Vue, пока просто пропустите эту секцию
Встроенных в HTML элементов ввода не всегда достаточно. К счастью, компоненты Vue позволяют создавать собственные аналоги с полностью настраиваемым поведением. Эти элементы тоже могут работать с директивой v-model
!
Подробнее в разделе пользовательские элементы ввода.