G
G
GrimJack2017-08-19 01:26:04
JavaScript
GrimJack, 2017-08-19 01:26:04

How to pass feedback between components?

Hello everyone, I've run into a problem. There is a parent component (form) and child (separate input).

parent
<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>


The bottom line is that I want to get feedback when I print text so that the data is immediately returned to the parent object. I assume that all this can be done without catching text input events.
Googled for a long time, but did not understand how to do it
How to do it correctly and without extra code?

Answer the question

In order to leave comments, you need to log in

3 answer(s)
E
Evgeny Kulakov, 2017-08-19
@GrimJack

It's normal practice to bounce an event up from your component if the parent needs it. This is your component's interface as it interacts with the outside world.

<input type="text" class="form-control" @input="$emit('input', $event)">

A
Alexander, 2017-08-19
@boratsagdiev

And what's the problem with catching the input event, making an emit in the ancestor and catching it in the parent? There is also a code of 10 lines.
If you don’t want to track keystrokes, you can hang a v-model on the input and make a watch to change it, send data to the parent when it changes (well, can you do an emit? :) I can’t think of anything without an event right away from the phone.

A
Andrey Sidorov, 2017-08-24
@morr

In order to have feedback, you need to pass an object / string / array (it doesn’t matter what exactly) from the parent component to the child component, which the child component will change.
Binding input to an object is done via the `v-model` attribute.
Whether vuex will be used or not is not important, the approach will not change in any way. Without vuex, you are passing an object that is in the parent component, and with vuex, you will be taking an object from the vuex store.
Edited your example a bit.

Parent
<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>
Descendant
<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>

In the screenshot, I highlighted the important points that from where take.ms/YvbyL is passed to
take.ms/7uGdO

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question