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

Узнайте как работать с формами в бесплатном уроке Vue School

# Обычное использование

Можно использовать директиву 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>
1
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>
1
2
3
4

See the Pen Работа с формами: многострочный текст by Vue (@Vue) on CodePen.

Интерполяция внутри textarea не работают. Используйте директиву v-model вместо неё.

<!-- НЕ РАБОТАЕТ -->
<textarea>{{ text }}</textarea>

<!-- ok -->
<textarea v-model="text"></textarea>
1
2
3
4
5

# Чекбоксы

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

<input type="checkbox" id="checkbox" v-model="checked" />
<label for="checkbox">{{ checked }}</label>
1
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>
1
2
3
4
5
6
7
8
9
10
Vue.createApp({
  data() {
    return {
      checkedNames: []
    }
  }
}).mount('#v-model-multiple-checkboxes')
1
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>
1
2
3
4
5
6
7
8
9
Vue.createApp({
  data() {
    return {
      picked: ''
    }
  }
}).mount('#v-model-radiobutton')
1
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>
1
2
3
4
5
6
7
8
9
Vue.createApp({
  data() {
    return {
      selected: ''
    }
  }
}).mount('#v-model-select')
1
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>
1
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>
1
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')
1
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>
1
2
3
4
5
6
7
8
9
10

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

# Чекбокс

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

// когда чекбокс сброшен
vm.toggle === 'нет'
1
2
3
4
5

Совет

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

# Радиокнопки

<input type="radio" v-model="pick" :value="a" />
1
// когда выбран
vm.pick === vm.a
1
2

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

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

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

# .lazy

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

<!-- синхронизация после события "change" вместо "input" -->
<input v-model.lazy="msg" />
1
2

# .number

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

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

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

# .trim

Если необходимо, чтобы пробельные символы в начале и в конце строки автоматически обрезались, то можно добавить модификатор trim для полей ввода, управляемых через v-model:

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

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

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

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

Подробнее в разделе пользовательские элементы ввода.