Разберем двустороннее связывание (two-way binding) на примере синхронизации хранимого в переменной значения и его визуального представления на метке и поле ввода.
Предположим, что у нас есть метка, на которой отображается имя города и соответствующая переменная city. Также есть поле ввода, где можно менять значение этой переменной. Это называется двусторонним связыванием, и его можно реализовать несколькими способами.
Итак, у нас есть компонент App.vue и компонент ввода Input.vue. Необходимо реализовать двустороннюю связь (two-way binding) значения этой переменной с тем, что вводится в Input.
[ref, defineEmits и defineProps]
Чтобы из компонента Input сообщить наверх, что произошли какие-то изменения при вводе, необходимо применить defineEmits. Передаваемое значение обычно обозначают в форме "событие:значение" следующим образом:
Здесь @input это событие, которое говорит о том, что произошел ввод текста. "emit('update:value', $event.target.value)" обозначает функцию, которая передает введенное значение.
Теперь при каждом нажатии кнопки будет передаваться событие о вводимом значении в родительский компонент App.vue.
Чтобы прочитать передаваемое значение, в родительском компоненте App.vue это значение надо принять:
Здесь @update:value="updateCity" обозначает прием генерируемого компонентом Input события, а updateCity это функция обработчика события. В ней вставлен вызов console.log, чтобы можно было в консоли браузера видеть вводимые изменения.
Чтобы вывести вводимое значение в родительском компоненте App.vue, необходимо с помощью ref обозначить его состояние:
Вводимое значение будет сразу появляться на форме родительского компонента.
Теперь надо задать какое-то значение по умолчанию, например "Москва", и обеспечить его появление в поле ввода как начальное значение. Это и будет "two-way binding".
// App.vue letcity=ref("Москва")
Для этого в компоненте Input необходимо определить defineProps:
С одной стороны, мы теперь при каждом вводе эмитим событие @input и передаем наверх вводимое значение, а с другой стороны мы получаем props и кладем его в поле ввода как значение по умолчанию.
Для этого в родительском компоненте App.vue также надо обновить использование компонента Input:
Теперь мы в App.vue слушаем событие ввода (@update:value="updateCity"), и одновременно передаем в поле ввода некоторое хранимое значение (:value="city"). Это и есть так называемое "two-way binding", когда мы связали двусторонней связью не только чтение, но и запись какого-то сохраненного значения (let city=ref("Москва")). Мы можем как задавать значение, так и обновлять его.
Очевидно, что такой способ двустороннего связывания получился довольно громоздким, поэтому существует удобная альтернатива: v-model.
[v-model]
Это более простой для использования способ двустороннего связывания. В шаблоне App.vue исправьте атрибуты компонента Input, заменив :value="city" и @update:value="updateCity" на один атрибут v-model="". Функцию updateCity теперь также можно удалить:
После этого в шаблоне можно использовать model в качестве привязанного через v-bind значения, и событие @input также определить не через emit, а через model:
Это все что нужно для организации двусторонней связи.
Также v-model может автоматически связываться с поведением стандартных элементов интерфейса ввода: input, textarea, checkbox, radio, selected, multiselect, все это будет работать. Т. е. можно заменить :v6alue= и @input= на единственный атрибут v-model="model", код становится еще более лаконичным
Этот параметр обязывает использовать v-model, и полезен для случаев, когда разрабочик забыл его указать. В этом случае в консоль браузера будет выводиться предупреждение: [Vue warn]: Missing required prop: "modelValue".
3. Третьим параметром в defineModel можно передать значение по умолчанию, если мы его не передали, например:
Здесь "mymodel" задает имя модели. Теперь можно указывать в атрибутах несколько моделей с помощью синтаксиса v-model:имя_модели, например (здесь в vmodel:mymodel="city" вместо city может быть другая переменная):
// Можно добавить реактивность на изменения
watch(count,(newValue)=>{ console.log('Новое значение:',newValue)
})
< /script>
Ключевые моменты:
1. v-model - основная директива для двустороннего связывания. 2. Реактивность - Vue автоматически обновляет DOM при изменении данных. 3. Методы и вычисляемые свойства - для дополнительной обработки значений. 4. События - можно использовать @input и @change для обработки изменений.
Выбор подхода зависит от конкретной задачи:
- Простое отображение: `v-model` + интерполяция `{{ }}`. - Сложная логика: вычисляемые свойства. - Кастомные компоненты: для повторного использования логики.