\n```\n\nВот что происходит под капотом:\n\n```javascript\n// v-model это сокращение для:\n\n```\n\n### Как работает v-model\n\n#### Шаг 1: Привязка значения (binding)\n\n```javascript\n\n\n// Эквивалентно:\n\n```\n\nДаннные из компонента **передаются в input**.\n\n#### Шаг 2: Обработка события (event handling)\n\n```javascript\n\n\n// Эквивалентно:\n\n```\n\nКогда пользователь меняет значение, событие **input** обновляет переменную в компоненте.\n\n### Примеры с разными элементами\n\n#### Input text\n\n```javascript\n\n\n\n```\n\n#### Textarea\n\n```javascript\n\n\n\n```\n\n#### Checkbox\n\n```javascript\n\n\n\n```\n\n#### Radio buttons\n\n```javascript\n\n\n\n```\n\n#### Select\n\n```javascript\n\n\n\n```\n\n### v-model на кастомных компонентах\n\nОсновная суть v-model — это **prop и emit событие**. Можно создать свой компонент с v-model:\n\n```javascript\n// Дочерний компонент: CustomInput.vue\n\n\n\n\n// Родительский компонент\n\n\n\n```\n\n### v-model с модификаторами\n\n#### .lazy - обновление при потере фокуса\n\n```javascript\n\n```\n\n#### .number - преобразование в число\n\n```javascript\n\n\n\n```\n\n#### .trim - удаление пробелов\n\n```javascript\n\n```\n\n### v-model vs React (для сравнения)\n\n```javascript\n// Vue - просто и коротко\nconst message = ref('');\n\n\n// React - длиннее\nconst [message, setMessage] = useState('');\n setMessage(e.target.value)} \n/>\n```\n\n### Частые ошибки\n\n#### Ошибка 1: Забыл ref()\n\n```javascript\n// НЕПРАВИЛЬНО\nlet message = '';\n // Не будет работать!\n\n// ПРАВИЛЬНО\nconst message = ref('');\n // Работает\n```\n\n#### Ошибка 2: v-model с props\n\n```javascript\n// НЕПРАВИЛЬНО - нельзя v-model с props напрямую\n\n\n // Плохая практика\n\n// ПРАВИЛЬНО - использовать computed с getter/setter\nconst userName = computed({\n get: () => props.user.name,\n set: (value) => emit('update:user', { ...props.user, name: value })\n});\n\n\n```\n\n### Резюме\n\n**v-model** — это удобный синтаксис для двусторонней привязки:\n- **Комбинирует** :value привязку и @input обработчик\n- **Работает** с input, textarea, select, checkbox, radio\n- **Можно использовать** в кастомных компонентах через props и emit\n- **Поддерживает модификаторы** (.lazy, .number, .trim)\n- **Значительно упрощает** работу с формами по сравнению с React","dateCreated":"2026-04-02T21:49:33.287405","upvoteCount":0,"author":{"@type":"Person","name":"claude-haiku-4.5"}}}}
← Назад к вопросам

Как работает v-model во Vue?

2.0 Middle🔥 221 комментариев
#State Management#Vue.js

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI2 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

v-model во Vue

Определение

v-model — это директива во Vue.js для создания двусторонней привязки данных между компонентом и элементом формы. Это синтаксический сахар, который комбинирует привязку значения и обработку события изменения.

То есть v-model одновременно:

  1. Отправляет значение в input/textarea/select
  2. Слушает изменения и обновляет данные

Базовый пример

// Vue 3 SFC
<template>
  <input v-model="message" />
  <p>Сообщение: {{ message }}</p>
</template>

<script setup>
import { ref } from 'vue';

const message = ref('');
// Когда пользователь пишет в input - message обновляется
// Когда message меняется - input обновляется
</script>

Вот что происходит под капотом:

// v-model это сокращение для:
<input 
  :value="message" 
  @input="message = $event.target.value" 
/>

Как работает v-model

Шаг 1: Привязка значения (binding)

<input v-model="username" />

// Эквивалентно:
<input :value="username" />

Даннные из компонента передаются в input.

Шаг 2: Обработка события (event handling)

<input v-model="username" />

// Эквивалентно:
<input @input="username = $event.target.value" />

Когда пользователь меняет значение, событие input обновляет переменную в компоненте.

Примеры с разными элементами

Input text

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

<script setup>
import { ref } from 'vue';
const name = ref('');
</script>

Textarea

<template>
  <textarea v-model="bio"></textarea>
  <p>{{ bio }}</p>
</template>

<script setup>
import { ref } from 'vue';
const bio = ref('');
</script>

Checkbox

<template>
  <input type="checkbox" v-model="isAgree" />
  <label>Я согласен с условиями</label>
  <p v-if="isAgree">Спасибо за согласие!</p>
</template>

<script setup>
import { ref } from 'vue';
const isAgree = ref(false);
</script>

Radio buttons

<template>
  <label>
    <input type="radio" value="male" v-model="gender" />
    Мужчина
  </label>
  <label>
    <input type="radio" value="female" v-model="gender" />
    Женщина
  </label>
  <p>Выбран пол: {{ gender }}</p>
</template>

<script setup>
import { ref } from 'vue';
const gender = ref('male');
</script>

Select

<template>
  <select v-model="selectedCountry">
    <option>Выберите страну</option>
    <option value="ru">Россия</option>
    <option value="us">США</option>
    <option value="uk">Великобритания</option>
  </select>
  <p>Выбранная страна: {{ selectedCountry }}</p>
</template>

<script setup>
import { ref } from 'vue';
const selectedCountry = ref('');
</script>

v-model на кастомных компонентах

Основная суть v-model — это prop и emit событие. Можно создать свой компонент с v-model:

// Дочерний компонент: CustomInput.vue
<template>
  <input 
    :value="modelValue" 
    @input="$emit('update:modelValue', $event.target.value)" 
    placeholder="Введите текст"
  />
</template>

<script setup>
defineProps(['modelValue']);
defineEmits(['update:modelValue']);
</script>

// Родительский компонент
<template>
  <CustomInput v-model="myText" />
  <p>Значение: {{ myText }}</p>
</template>

<script setup>
import { ref } from 'vue';
import CustomInput from './CustomInput.vue';
const myText = ref('');
</script>

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

.lazy - обновление при потере фокуса

<template>
  <!-- Обновляется только когда пользователь уходит из input -->
  <input v-model.lazy="message" />
</template>

.number - преобразование в число

<template>
  <!-- Автоматически преобразует строку в число -->
  <input v-model.number="age" type="number" />
  <!-- age всегда будет число, не строка -->
</template>

<script setup>
import { ref } from 'vue';
const age = ref(0);
</script>

.trim - удаление пробелов

<template>
  <!-- Удаляет пробелы в начале и конце -->
  <input v-model.trim="username" />
</template>

v-model vs React (для сравнения)

// Vue - просто и коротко
const message = ref('');
<input v-model="message" />

// React - длиннее
const [message, setMessage] = useState('');
<input 
  value={message} 
  onChange={(e) => setMessage(e.target.value)} 
/>

Частые ошибки

Ошибка 1: Забыл ref()

// НЕПРАВИЛЬНО
let message = '';
<input v-model="message" />  // Не будет работать!

// ПРАВИЛЬНО
const message = ref('');
<input v-model="message" />  // Работает

Ошибка 2: v-model с props

// НЕПРАВИЛЬНО - нельзя v-model с props напрямую
<script setup>
defineProps(['user']);
</script>

<input v-model="user.name" />  // Плохая практика

// ПРАВИЛЬНО - использовать computed с getter/setter
const userName = computed({
  get: () => props.user.name,
  set: (value) => emit('update:user', { ...props.user, name: value })
});

<input v-model="userName" />

Резюме

v-model — это удобный синтаксис для двусторонней привязки:

  • Комбинирует :value привязку и @input обработчик
  • Работает с input, textarea, select, checkbox, radio
  • Можно использовать в кастомных компонентах через props и emit
  • Поддерживает модификаторы (.lazy, .number, .trim)
  • Значительно упрощает работу с формами по сравнению с React