Перейти к содержанию

Привязка элементов формы

При работе с формами на фронтенде нам часто требуется синхронизировать состояние элементов ввода формы с соответствующим состоянием в 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, используя свойство dataReactivity 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([])
js
export default {
  data() {
    return {
      checkedNames: []
    }
  }
}
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' }
])
js
export default {
  data() {
    return {
      selected: 'A',
      options: [
        { text: 'Один', value: 'A' },
        { text: 'Два', value: 'B' },
        { text: 'Три', value: 'C' }
      ]
    }
  }
}
template
<select v-model="selected">
  <option v-for="option in options" :value="option.value">
    {{ option.text }}
  </option>
</select>

<div>Выбрано: {{ selected }}</div>

Привязка значения

Для элементов 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 в руководстве по компонентам.

Привязка элементов формы