Как реализовать двухстороннюю привязку?vue-23

Двухсторонняя привязка данных — это фундаментальная концепция Vue.js, позволяющая синхронизировать данные между компонентами и элементами формы. Vue предоставляет несколько способов реализации этой функциональности.

Основной способ: Директива v-model

Синтаксический сахар для двустороннего связывания данных с элементами формы:

<template>
  <input v-model="message" placeholder="Редактируйте меня">
  <p>Введённое сообщение: {{ message }}</p>
</template>

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

Как это работает:

  1. При изменении поля ввода обновляется свойство message
  2. При изменении message обновляется значение поля ввода

Под капотом v-model

Директива v-model — это синтаксический сахар для:

  • Привязки значения (:value)
  • Обработки события ввода (@input)

Эквивалентная реализация без v-model:

<input
  :value="message"
  @input="message = $event.target.value"
>

Работа с компонентами

Для кастомных компонентов нужно реализовать интерфейс v-model:

1. Использование modelValue

<CustomInput v-model="searchText" />

Реализация в компоненте:

<template>
  <input
    :value="modelValue"
    @input="$emit('update:modelValue', $event.target.value)"
  >
</template>

<script>
export default {
  props: ['modelValue'],
  emits: ['update:modelValue']
}
</script>

2. Альтернатива для Vue 2

<CustomInput v-model="searchText" />

Реализация компонента:

<template>
  <input
    :value="value"
    @input="$emit('input', $event.target.value)"
  >
</template>

<script>
export default {
  props: ['value']
}
</script>

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

Vue предоставляет встроенные модификаторы:

  • .lazy - обновляет данные по событию change вместо input
  • .number - автоматически преобразует ввод в число
  • .trim - удаляет пробелы с обоих концов

Пример:

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

Кастомные модификаторы

Можно создавать собственные модификаторы через объект model:

export default {
  model: {
    prop: 'checked',
    event: 'change',
    modifier: (value) => value.toUpperCase() // Кастомный модификатор
  }
}

Продвинутые техники

1. Множественные v-model

<UserName
  v-model:first-name="first"
  v-model:last-name="last"
/>

2. Связывание с вычисляемыми свойствами

computed: {
  fullName: {
    get() {
      return `${this.firstName} ${this.lastName}`;
    },
    set(value) {
      const names = value.split(' ');
      this.firstName = names[0];
      this.lastName = names[1] || '';
    }
  }
}

Ограничения и лучшие практики

  1. Не злоупотребляйте двухсторонней привязкой для сложных структур данных
  2. Для глубоких объектов используйте .sync (Vue 2) или v-model:propName (Vue 3)
  3. Всегда валидируйте входящие данные
  4. Для неуправляемых компонентов рассмотрите использование ref

Резюмируем:

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