Как прокинуть обратную связь между компонентами?

Всем привет, столкнулся с проблемой. Есть родительский компонент (форма) и дочерний (отдельный инпут).
родитель
<template>
<form>
   <c-input :data="data"></c-input>
  <button> Отправить</button>
  </form>
</template>

<style>
    @import "../../sass/dashboard.scss";
</style>

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

c-input
<template>
    <div class="form-group">
        <input type="text" class="form-control" :class="properties.append" :value="properties.value" :placeholder="properties.placeholder" :name="properties.name" :id="properties.name">
        <label :for="properties.name" generated="true" class="error" v-if="properties.error">{{ properties.error }}</label>
    </div>
</template>

<script>
    export default {
        props: ['data'],
        data() {
            return {
                properties: {
                    name: Math.random().toString(36).replace(/[^a-z]+/g, '').substr(0, 5),
                    append: '',
                    value: '',
                    placeholder: '',
                    error: false
                }
            }
        },
        created() {
            for(let param in this.data){
                if(this.properties.hasOwnProperty(param)){
                    this.properties[param] = this.data[param];
                }
            }
            if(this.properties.error){
                this.properties.append += ' error';
            }
        }
    }
</script>


Суть в том, что я хочу получить обратную связь, когда я печатаю текст, что-бы данные сразу возвращались в объект родителя. Предполагаю, что это все можно сделать без отлавливания событий ввода текста.
Долго гуглил, но так и не понял как это сделать
Как это сделать правильно и без лишнего кода?
  • Вопрос задан
  • 781 просмотр
Решения вопроса 1
kulakoff
@kulakoff Куратор тега Vue.js
Vue.js developing
Нормальная практика пробрасывать событие наверх от своего компонента, если родитель в нем нуждается. Это есть ваш интерфейс компонента при его взаимодействии с внешним миром.

<input type="text" class="form-control" @input="$emit('input', $event)">
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 2
boratsagdiev
@boratsagdiev
А в чем проблема отловить событие ввода, сделать emit в предке и поймать его в родителе? Тут же кода строк на 10.

Если не хочется отслеживать нажатие клавиш, можно повесить на input v-model и сделать watch на его изменение, при изменении прокидывать данные в родителя (ну тут уж можете сделать emit? :) без события сходу не придумаю ничего с телефона.
Ответ написан
Чтобы была обратная связь, вам из родительского компонента в дочерний нужно передать объект/строку/массив (не суть важно что именно), который дочерний компонент будет изменять.
Привязка input к объекту делается через атрибут `v-model`.

Будет ли при этом использоваться vuex или нет, это не важно, подход при этом никак не изменится. Без vuex вы передаёте объект, лежащий в родительском компонента, а с vuex будете брать объект из vuex хранилища.

Немного отредактировал ваш пример
Родитель
<template lang="pug">
  form
    div you wrote: {{input_data.value != '' ? input_data.value : 'nothing'}}
    c_input(
      :input_data="input_data"
    )
    button Отправить
</template>

<script>
import c_input from './test_2'
export default {
  components: { c_input },
  data() {
    return {
      input_data: {
        name: Math.random().toString(36).replace(/[^a-z]+/g, '').substr(0, 5),
        append: '',
        value: '',
        placeholder: '',
        error: 'zz'
      }
    }
  }
}
</script>
Потомок
<template lang="pug">
  .form-group
    input(
      type="text"
      class="form-control"
      :class="input_data.append"
      v-model="input_data.value"
      :placeholder="input_data.placeholder"
      :name="input_data.name"
      :id="input_data.name"
    )
    label(
      :for="input_data.name"
      generated="true"
      class="error"
      v-if="input_data.error"
    ) error: {{ input_data.error }}
  </div>
</template>

<script>
  export default {
    props: {
      input_data: Object
    }
  }
</script>


На скриншоте выделил важные моменты что откуда куда передаётся take.ms/YvbyL
take.ms/7uGdO
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы