Работа с v-model

v-model — это директива двухсторонней привязки данных, которая связывает значение элемента формы с состоянием компонента. Она упрощает синхронизацию пользовательского ввода и данных приложения, снижая количество шаблонного кода и повышая читаемость.


Основное использование v-model

Наиболее простой пример применения v-model — привязка текстового поля к свойству объекта data:

<template>
  <input v-model="username" placeholder="Введите имя">
  <p>Привет, {{ username }}!</p>
</template>

<script>
export default {
  data() {
    return {
      username: ''
    }
  }
}
</script>

При каждом изменении значения в input свойство username автоматически обновляется. Изменения в username также мгновенно отражаются в поле ввода.


Двусторонняя привязка для различных элементов формы

v-model работает не только с текстовыми полями. Поддерживаются следующие элементы:

  • Checkbox
<input type="checkbox" v-model="isSubscribed">

Если isSubscribed — булево значение, чекбокс автоматически синхронизируется с ним.

  • Radio
<input type="radio" v-model="selectedOption" value="A"> A
<input type="radio" v-model="selectedOption" value="B"> B

Значение selectedOption меняется в зависимости от выбранного радио.

  • Select
<SELECT v-model="selectedItem">
  <option value="1">Первый</option>
  <option value="2">Второй</option>
</select>

selectedItem будет равен значению выбранной опции.

  • Multiple select
<select v-model="selectedItems" multiple>
  <option value="1">Первый</option>
  <option value="2">Второй</option>
</select>

selectedItems становится массивом выбранных значений.


Модификаторы v-model

Vue.js предоставляет несколько модификаторов, которые меняют поведение привязки:

  • .lazy — обновляет модель только после события change, а не на каждом вводе.
<input v-model.lazy="username">
  • .number — преобразует ввод в число.
<input v-model.number="age" type="number">
  • .trim — автоматически обрезает пробелы в начале и конце строки.
<input v-model.trim="username">

Модификаторы можно комбинировать: v-model.lazy.number.


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

С Vue 3 v-model может использоваться для передачи значений в кастомные компоненты. В этом случае компонент должен явно принимать modelValue как prop и испускать событие update:modelValue.

<template>
  <CustomInput v-model="textValue" />
</template>

<script>
import CustomInput FROM './CustomInput.vue'

export default {
  components: { CustomInput },
  data() {
    return {
      textValue: ''
    }
  }
}
</script>

Внутри CustomInput.vue:

<template>
  <input :value="modelValue" @input="$emit('update:modelValue', $event.target.value)">
</template>

<script>
export default {
  props: ['modelValue']
}
</script>

Таким образом, любой компонент можно сделать полностью совместимым с v-model.


Именованные v-model

Vue 3 позволяет использовать несколько v-model для одного компонента с разными свойствами.

<CustomInput v-model:title="title" v-model:content="content" />

В компоненте нужно указать соответствующие props и события:

props: ['title', 'content'],
emits: ['update:title', 'update:content']

Это дает возможность синхронизировать несколько состояний одного компонента без лишних вычисляемых свойств.


Рекомендации по использованию

  • Использовать v-model для всех элементов формы для упрощения синхронизации данных.
  • Для сложных компонентов создавать явные props и события update:modelValue.
  • Применять модификаторы .lazy, .number и .trim для удобной валидации и обработки данных.
  • Избегать изменения v-model напрямую внутри методов, лучше работать через вычисляемые свойства или методы, чтобы не нарушать принцип одностороннего потока данных.

v-model является ключевым инструментом для создания реактивных форм и компонентов в Vue.js, упрощая код и повышая его читаемость.