Привязка элементов формы
При работе с формами на фронтенде нам часто требуется синхронизировать состояние элементов ввода формы с соответствующим состоянием в 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, используя Reactivity API.
Основы
Текст (input type="text")
template
<p>Сообщение: {{ message }}</p>
<input v-model="message" placeholder="измени меня" />Сообщение:
Примечание
Для языков, требующих IME (китайский, японский, корейский и т. д.), вы заметите, что v-model не обновляется во время составления IME. Если вы хотите реагировать и на эти обновления, используйте свой собственный слушатель событий input и привязку value вместо использования v-model.
Многострочный текст (textarea)
template
<span>Многострочное сообщение:</span>
<p style="white-space: pre-line;">{{ message }}</p>
<textarea v-model="message" placeholder="добавь несколько строк"></textarea>Многострочное сообщение:
Обратите внимание, что интерполяция внутри <textarea> не будет работать. Вместо этого используйте v-model.
template
<!-- bad -->
<textarea>{{ text }}</textarea>
<!-- good -->
<textarea v-model="text"></textarea>Флажок (input type="checkbox")
Одиночный флажок, булево значение:
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="Женя" 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>Отмеченные имена: []
В этом случае массив checkedNames всегда будет содержать значения из текущих отмеченных флажков.
Переключатель (input type="radio")
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">TДва/label>Выбрано:
Выпадающий список (select)
Выбор одного значения:
template
<div>Выбрано: {{ selected }}</div>
<select v-model="selected">
<option disabled value="">Выберите что-нибудь</option>
<option>A</option>
<option>B</option>
<option>C</option>
</select>Выбрано:
Примечание
Если начальное значение выражения v-model не соответствует ни одному из вариантов, элемент <select> будет отображаться в виде unselected. На iOS это приведет к тому, что пользователь не сможет выбрать первый элемент, потому что iOS не запускает событие изменения в этом случае. Поэтому рекомендуется предоставлять опцию disabled с пустым значением, как показано в примере выше.
Множественный выбор (привязка к массиву):
template
<div>Выбрано: {{ selected }}</div>
<select v-model="selected" multiple>
<option>A</option>
<option>B</option>
<option>C</option>
</select>Выбрано: []
Варианты выбора могут быть динамически отображены с помощью v-for:
js
const selected = ref('A')
const options = ref([
{ text: 'Один', value: 'A' },
{ text: 'Два', value: 'B' },
{ text: 'Три', value: 'C' }
])template
<div>Выбрано: {{ selected }}</div>
<select v-model="selected">
<option v-for="option in options" :value="option.value">
{{ option.text }}
</option>
</select>Выбрано: A
Привязка значения
Для элементов radio, checkbox и select значения привязки v-model обычно являются статическими строками (или булевыми значениями для checkbox):
template
<!-- `picked` это строка "a" при выборе -->
<input type="radio" v-model="picked" value="a" />
<!-- `toggle` является либо истинным, либо ложным -->
<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="yes"
false-value="no" />true-value и false-value — специфические для Vue атрибуты, которые работают только с v-model. Здесь значение свойства toggle будет установлено в 'yes', когда флажок установлен, и в 'no', когда флажок снят. Вы также можете привязать их к динамическим значениям с помощью v-bind:
template
<input
type="checkbox"
v-model="toggle"
:true-value="dynamicTrueValue"
:false-value="dynamicFalseValue" />Совет
Атрибуты true-value и false-value не влияют на атрибут value элемента ввода, потому что браузеры не включают в формы не отмеченные флажки. Чтобы гарантировать, что в форме будет представлено одно из двух значений (например, «yes» или «no»), используйте вместо флажков переключатели.
Переключатель
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 к атрибуту v-model:
template
<input v-model.number="age" />Если значение не может быть разобрано с помощью parseFloat(), то вместо него используется исходное (строковое) значение. В частности, если поле ввода пустое (например, после того, как пользователь его очистил), возвращается пустая строка. Это поведение отличается от DOM-свойства valueAsNumber.
Модификатор number применяется автоматически, если входные данные имеют type="number".
.trim
Если вы хотите, чтобы пробельные символы из пользовательского ввода обрезались автоматически, вы можете добавить модификатор trim к атрибуту v-model:
template
<input v-model.trim="msg" />v-model с компонентами
Если вы ещё не знакомы с компонентами Vue, можете пока пропустить этот пункт.
Встроенные типы ввода HTML не всегда могут удовлетворить ваши потребности. К счастью, компоненты Vue позволяют создавать многоразовые элементы ввода с полностью настраиваемым поведением. Эти элементы ввода также работают с v-model! Чтобы узнать больше, прочитайте про использование v-model в руководстве по компонентам.