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

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

<template>
  <input v-model="message" placeholder="Введите текст">
  <p>Вы ввели: {{ message }}</p>
</template>

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

В примере выше переменная message синхронизирована с полем ввода. Любое изменение в поле автоматически обновляет message, и любое изменение message обновляет поле ввода.

Применение v-model с различными типами элементов

v-model работает не только с текстовыми полями:

  • Checkbox — привязка к булевым значениям или массивам:
<input type="checkbox" v-model="checked">
<input type="checkbox" v-model="selectedColors" value="red">
  • Radio — привязка к одному значению:
<input type="radio" v-model="picked" value="A">
<input type="radio" v-model="picked" value="B">
  • Select — привязка к выбранному значению или массиву значений:
<SELECT v-model="selected">
  <option value="apple">Яблоко</option>
  <option value="banana">Банан</option>
</select>

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

Модификаторы позволяют изменять поведение двусторонней привязки без использования дополнительных методов или вычисляемых свойств.

.lazy

Задерживает обновление данных до события change вместо стандартного input. Используется для оптимизации при частых вводах.

<input v-model.lazy="message">

При этом message обновится только после того, как пользователь покинет поле ввода или нажмет Enter.

.number

Автоматически преобразует ввод в числовой тип, исключая необходимость явного преобразования через parseInt или parseFloat.

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

Если пользователь вводит "42", значение в состоянии будет числом 42.

.trim

Удаляет пробелы в начале и конце строки при обновлении переменной.

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

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

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

v-model можно использовать не только с нативными элементами, но и с собственными компонентами. Для этого компонент должен принимать modelValue через props и эмитить событие update:modelValue.

// Компонент MyInput.vue
<template>
  <input :value="modelValue" @input="$emit('update:modelValue', $event)">
</template>

<script>
export default {
  props: ['modelValue']
}
</script>
<template>
  <MyInput v-model="textValue"/>
</template>

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

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

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

Комбинирование модификаторов

Модификаторы могут использоваться одновременно для достижения комбинированного эффекта:

<input v-model.lazy.trim.number="score">

Здесь ввод будет:

  • Обновлять данные только после события change (.lazy),
  • Убирать лишние пробелы (.trim),
  • Преобразовываться в число (.number).

Важные нюансы

  • v-model работает только с реактивными данными, объявленными в data или через ref в Composition API.
  • Для объектов и массивов изменения должны происходить через реактивные методы (push, splice) или через присваивание нового объекта/массива.
  • При использовании нескольких v-model в компоненте необходимо явно задать аргументы:
<MyComponent v-model:title="pageTitle" v-model:content="pageContent"/>

Аргументы позволяют создавать независимые привязки для разных свойств компонента.

Практическое применение

v-model с модификаторами часто используется для:

  • Форм ввода с валидацией,
  • Настройки фильтров и параметров отображения,
  • Связывания состояния UI с моделью данных в реальном времени,
  • Компонентов типа слайдеров, чекбоксов, радиокнопок и выпадающих списков.

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