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

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

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

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

Внутренне v-model использует разные свойства и генерирует разные события для различных элементов ввода:

В языках, требующих 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 для полей ввода, обрабатываемых через v-model:

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

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

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

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