\n```\n\nЭто эквивалентно:\n\n```javascript\n\n```\n\n### v-model на компонентах\n\nВ Vue 3 можно использовать v-model на **custom компонентах**:\n\n```javascript\n// Родитель\n\n\n\n```\n\n**Компонент MyCheckbox:**\n\n```javascript\n\n\n\n```\n\nKey points:\n- **Prop** называется `modelValue` (специальное имя для v-model)\n- **Event** называется `update:modelValue` (специальное имя)\n- Родитель автоматически обновляет переменную при emit\n\n### Множественные v-model (Vue 3)\n\nВ Vue 3 можно использовать несколько v-model на одном компоненте:\n\n```javascript\n// Родитель\n\n\n\n```\n\n**Компонент UserProfile:**\n\n```javascript\n\n\n\n```\n\n### Как это работает под капотом\n\n**Шаг 1: Инициализация**\n```javascript\ndata() { return { message: \"\" }; }\n// Vue создаёт реактивное свойство\n```\n\n**Шаг 2: Привязка значения**\n```javascript\n// v-model привязывает value элемента к свойству\n\n// При изменении message -> input.value обновляется автоматически\n```\n\n**Шаг 3: Обработка события**\n```javascript\n// v-model слушает событие input\n\n// Когда пользователь печатает -> событие input\n// message обновляется -> шаг 2 повторяется\n```\n\n### Реактивность в Vue\n\nВсё это работает благодаря **реактивной системе Vue**:\n\n```javascript\nexport default {\n data() {\n return { count: 0 }; // Vue делает это реактивным\n },\n watch: {\n count(newValue, oldValue) {\n console.log(`count изменился с ${oldValue} на ${newValue}`);\n }\n }\n};\n```\n\nVue отслеживает изменения и автоматически обновляет DOM.\n\n### Модификаторы v-model\n\n```javascript\n// .lazy - обновление только на blur\n\n\n// .number - преобразование в число\n\n\n// .trim - удаление пробелов\n\n\n// Комбинирование\n\n```\n\n### Пример: Custom input компонент\n\n```javascript\n\n\n\n\n// Использование\n\n```\n\n### Производительность: computed property с getter/setter\n\nДля сложной логики можно использовать computed свойство:\n\n```javascript\n\n\n\n```\n\nПри изменении input обе части обновляются одновременно.\n\n### Вывод\n\n**v-model** — это синтаксический сахар для комбинирования **prop для значения** и **события обновления**. Работает через реактивную систему Vue, которая отслеживает изменения и синхронизирует DOM автоматически. В Vue 3 поддерживает множественные v-model на одном компоненте, что делает его мощным инструментом для двухстороннего связывания данных.","dateCreated":"2026-04-02T22:22:58.164092","upvoteCount":0,"author":{"@type":"Person","name":"claude-haiku-4.5"}}}}
← Назад к вопросам

Как работает двухстороннее связывание в VModal?

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

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

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

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

Как работает двухстороннее связывание в v-model

Что такое v-model

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

Основной механизм: prop + emit

v-model на самом деле работает через комбинацию:

  1. Prop для передачи данных в компонент
  2. 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 на одном компоненте, что делает его мощным инструментом для двухстороннего связывания данных.

Как работает двухстороннее связывание в VModal? | PrepBro