Как можно передать данные из дочернего компонента в родительский во Vue 3?

Как получить значение input компонента в родительском компоненте после перемещения input внутрь дочернего компонента?
  • 14 января 2024 г. 11:28
Ответы на вопрос 2
В Vue 3 для передачи данных из дочернего компонента в родительский обычно используются пользовательские события. Рассмотрим, как это реализуется на примере компонентов, где в дочернем компоненте находится элемент `input`.

### Шаг 1: Создать дочерний компонент

Создаем дочерний компонент с элементом `input` и используем директиву `v-model` для связывания значения поля с переменной из data дочернего компонента.

Дочерний компонент (ChildComponent.vue):
```vue
<template>
  <input type="text" :value="inputValue" @input="handleChange">
</template>

<script>
export default {
  name: 'ChildComponent',
  props: {
    value: String,
  },
  data() {
    return {
      inputValue: this.value,
    };
  },
  methods: {
    handleChange(event) {
      const newValue = event.target.value;
      this.inputValue = newValue;
      // Вызываем событие input, передавая новое значение в родительский компонент
      this.$emit('update:value', newValue);
    },
  },
};
</script>
```

В этом примере мы создаем пользовательское событие `update:value`, которое отправляется с новым значением в родительский компонент каждый раз, когда пользователь вводит символы в `input`.

### Шаг 2: Использование дочернего компонента в родительском

Теперь надо использовать дочерний компонент в родительском и установить обработчик для события `update:value`, чтобы получить новое значение в родительском компоненте.

Родительский компонент (ParentComponent.vue):
```vue
<template>
  <div>
    <child-component :value="inputValue" @update:value="inputValue = $event" />
    <p>Значение из дочернего компонента: {{ inputValue }}</p>
  </div>
</template>

<script>
import ChildComponent from './ChildComponent.vue';

export default {
  name: 'ParentComponent',
  components: {
    ChildComponent,
  },
  data() {
    return {
      inputValue: '',
    };
  },
};
</script>
```

В этом коде родительский компонент прослушивает `update:value` события от дочернего компонента и обновляет свою локальную переменную `inputValue`.

### Краткое описание использования `v-model` с компонентами

С Vue 3 можно использовать `v-model` с компонентами, что позволяет создать двустороннее связывание. Новый подход с использованием `v-model` на дочернем компоненте выглядел бы так:

Дочерний компонент (ChildComponent.vue):
```vue
<template>
  <input type="text" :value="modelValue" @input="updateModel($event.target.value)">
</template>

<script>
export default {
  props: {
    modelValue: String, // используем modelValue вместо value для props по умолчанию
  },
  emits: ['update:modelValue'], // определяем, что компонент может издавать это событие
  methods: {
    updateModel(value) {
      this.$emit('update:modelValue', value);
    },
  },
};
</script>
```

Родительский компонент (ParentComponent.vue):
```vue
<template>
  <div>
    <child-component v-model="inputValue" />
    <p>Значение из дочернего компонента: {{ inputValue }}</p>
  </div>
</template>

<script>
import ChildComponent from './ChildComponent.vue';

export default {
  components: {
    ChildComponent,
  },
  data() {
    return {
      inputValue: '',
    };
  },
};
</script>
```

Используя `v-model`, вы автоматически привязываете `modelValue` к значению родителя и обрабатываете событие `update:model
<template>
  <input
    :value="props.modelValue"
    @input="emit('update:modelValue', $event.target.value)"
  />
</template>

<script setup>
const props = defineProps(['modelValue'])
const emit = defineEmits(['update:modelValue'])
</script>


<template>
  <new-component v-model="refInput" />
</template>
<script setup>
import { ref } from 'vue'
import NewComponent from './new-component'
const refInput = ref('')
Похожие вопросы