Как работает двухстороннее связывание в VModal?
Комментарии (2)
Ответ сгенерирован нейросетью и может содержать ошибки
Как работает двухстороннее связывание в v-model
Что такое v-model
v-model — это директива Vue, которая создает двухстороннее связывание (two-way binding) между данными компонента и элементом формы. Это синтаксический сахар, который комбинирует привязку свойства и обработчик события.
Основной механизм: prop + emit
v-model на самом деле работает через комбинацию:
- Prop для передачи данных в компонент
- Event emit для отправки изменений обратно
// Родительский компонент
<template>
<input v-model="message" />
<p>{{ message }}</p>
</template>
<script>
export default {
data() {
return {
message: "Привет"
};
}
};
</script>
Это эквивалентно:
<template>
<input
:value="message"
@input="message = $event.target.value"
/>
<p>{{ message }}</p>
</template>
v-model на компонентах
В Vue 3 можно использовать v-model на custom компонентах:
// Родитель
<template>
<MyCheckbox v-model="isChecked" />
<p>{{ isChecked }}</p>
</template>
<script>
export default {
data() {
return {
isChecked: true
};
}
};
</script>
Компонент MyCheckbox:
<template>
<input
type="checkbox"
:checked="modelValue"
@change="$emit('update:modelValue', $event.target.checked)"
/>
</template>
<script>
export default {
props: ['modelValue'],
emits: ['update:modelValue']
};
</script>
Key points:
- Prop называется
modelValue(специальное имя для v-model) - Event называется
update:modelValue(специальное имя) - Родитель автоматически обновляет переменную при emit
Множественные v-model (Vue 3)
В Vue 3 можно использовать несколько v-model на одном компоненте:
// Родитель
<template>
<UserProfile
v-model:name="userName"
v-model:email="userEmail"
/>
</template>
<script>
export default {
data() {
return {
userName: "Алиса",
userEmail: "alice@example.com"
};
}
};
</script>
Компонент UserProfile:
<template>
<input
:value="name"
@input="$emit('update:name', $event.target.value)"
/>
<input
:value="email"
@input="$emit('update:email', $event.target.value)"
/>
</template>
<script>
export default {
props: ['name', 'email'],
emits: ['update:name', 'update:email']
};
</script>
Как это работает под капотом
Шаг 1: Инициализация
data() { return { message: "" }; }
// Vue создаёт реактивное свойство
Шаг 2: Привязка значения
// v-model привязывает value элемента к свойству
<input :value="message" />
// При изменении message -> input.value обновляется автоматически
Шаг 3: Обработка события
// v-model слушает событие input
<input @input="message = $event.target.value" />
// Когда пользователь печатает -> событие input
// message обновляется -> шаг 2 повторяется
Реактивность в Vue
Всё это работает благодаря реактивной системе Vue:
export default {
data() {
return { count: 0 }; // Vue делает это реактивным
},
watch: {
count(newValue, oldValue) {
console.log(`count изменился с ${oldValue} на ${newValue}`);
}
}
};
Vue отслеживает изменения и автоматически обновляет DOM.
Модификаторы v-model
// .lazy - обновление только на blur
<input v-model.lazy="message" />
// .number - преобразование в число
<input v-model.number="age" />
// .trim - удаление пробелов
<input v-model.trim="text" />
// Комбинирование
<input v-model.lazy.trim="message" />
Пример: Custom input компонент
<template>
<div class="custom-input">
<label>{{ label }}</label>
<input
:value="modelValue"
@input="$emit('update:modelValue', $event.target.value)"
:placeholder="placeholder"
/>
</div>
</template>
<script>
export default {
props: {
modelValue: String,
label: String,
placeholder: String
},
emits: ['update:modelValue']
};
</script>
// Использование
<CustomInput
v-model="userName"
label="Имя пользователя"
placeholder="Введите имя"
/>
Производительность: computed property с getter/setter
Для сложной логики можно использовать computed свойство:
<template>
<input v-model="fullName" />
</template>
<script>
export default {
data() {
return {
firstName: "Иван",
lastName: "Петров"
};
},
computed: {
fullName: {
get() {
return `${this.firstName} ${this.lastName}`;
},
set(value) {
const [first, last] = value.split(' ');
this.firstName = first;
this.lastName = last;
}
}
}
};
</script>
При изменении input обе части обновляются одновременно.
Вывод
v-model — это синтаксический сахар для комбинирования prop для значения и события обновления. Работает через реактивную систему Vue, которая отслеживает изменения и синхронизирует DOM автоматически. В Vue 3 поддерживает множественные v-model на одном компоненте, что делает его мощным инструментом для двухстороннего связывания данных.