← Назад к вопросам
Как работает навешанный на input VModal?
2.0 Middle🔥 231 комментариев
#JavaScript Core
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI3 апр. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Что такое v-model в Vue
v-model - это двусторонняя привязка данных (two-way binding) в Vue. Она связывает значение input с переменной в компоненте. При изменении input обновляется переменная и наоборот.
Как работает v-model на input
// Что происходит под капотом
<input v-model="message" />
// Эквивалентно:
<input
:value="message"
@input="message = $event.target.value"
/>
// То есть:
// 1. :value привязывает текущее значение message
// 2. @input обновляет message при вводе пользователя
Решение 1: Базовое использование v-model
<template>
<input v-model="name" type="text" placeholder="Enter name" />
<p>You typed: {{ name }}</p>
<textarea v-model="message"></textarea>
<p>Message: {{ message }}</p>
<input v-model="count" type="number" />
<p>Count: {{ count }}</p>
<input v-model="agree" type="checkbox" />
<p>Agree: {{ agree }}</p>
</template>
<script setup>
import { ref } from 'vue';
const name = ref('');
const message = ref('');
const count = ref(0);
const agree = ref(false);
</script>
Решение 2: v-model с модификаторами
<template>
<!-- lazy - обновляет при blur -->
<input v-model.lazy="name" />
<!-- number - преобразует в число -->
<input v-model.number="age" type="number" />
<!-- trim - убирает пробелы -->
<input v-model.trim="message" />
<!-- Комбинирование -->
<input v-model.trim.number="price" type="number" />
</template>
<script setup>
import { ref } from 'vue';
const name = ref('');
const age = ref(0);
const message = ref('');
const price = ref(0);
</script>
Решение 3: v-model в кастомных компонентах
// Родительский компонент
<template>
<CustomInput v-model="formData.email" />
<p>Email: {{ formData.email }}</p>
</template>
<script setup>
import { reactive } from 'vue';
import CustomInput from './CustomInput.vue';
const formData = reactive({
email: ''
});
</script>
// CustomInput.vue - кастомный компонент
<template>
<input
:value="modelValue"
@input="$emit('update:modelValue', $event.target.value)"
type="email"
placeholder="Enter email"
/>
</template>
<script setup>
defineProps({
modelValue: String
});
defineEmits(['update:modelValue']);
</script>
Решение 4: v-model с несколькими значениями
// Родительский компонент
<template>
<MultiInput
v-model:email="user.email"
v-model:phone="user.phone"
v-model:name="user.name"
/>
<pre>{{ user }}</pre>
</template>
<script setup>
import { reactive } from 'vue';
import MultiInput from './MultiInput.vue';
const user = reactive({
email: '',
phone: '',
name: ''
});
</script>
// MultiInput.vue
<template>
<input
:value="email"
@input="$emit('update:email', $event.target.value)"
placeholder="Email"
/>
<input
:value="phone"
@input="$emit('update:phone', $event.target.value)"
placeholder="Phone"
/>
<input
:value="name"
@input="$emit('update:name', $event.target.value)"
placeholder="Name"
/>
</template>
<script setup>
defineProps({
email: String,
phone: String,
name: String
});
defineEmits(['update:email', 'update:phone', 'update:name']);
</script>
Решение 5: v-model с валидацией
<template>
<div>
<input
v-model.trim="internalValue"
type="email"
@blur="validate"
:class="{ 'border-red-500': error }"
/>
<p v-if="error" class="text-red-500">{{ error }}</p>
</div>
</template>
<script setup>
import { computed, ref } from 'vue';
const props = defineProps({
modelValue: String
});
const emit = defineEmits(['update:modelValue']);
const error = ref('');
const internalValue = computed({
get: () => props.modelValue,
set: (value) => {
emit('update:modelValue', value);
}
});
const validate = () => {
if (!internalValue.value) {
error.value = 'Email is required';
return;
}
const emailRegex = /^[^@]+@[^@]+\.[^@]+$/;
if (!emailRegex.test(internalValue.value)) {
error.value = 'Invalid email format';
return;
}
error.value = '';
};
</script>
Важные моменты
- v-model на input: автоматически обновляет значение при вводе
- Модификаторы: lazy, number, trim для удобства
- Кастомные компоненты: используй emit('update:modelValue')
- Несколько v-model: в Vue 3 можно привязывать несколько значений
- Под капотом: это просто :value + @input/change