Home > Enterprise >  Vue: Pass parent data to child when updated with button click
Vue: Pass parent data to child when updated with button click

Time:01-06

I am new to Vue and trying to pass data from a parent component to the child when the parent data is updated via button click. The parent data is being updated, but the updated data is not being passed onto the child.

My main App.vue file is fairly standard:

<template>
  <div id="app">
    <parent></parent>
  </div>
</template>


<script>

import parent from './components/parent.vue';
export default {
  components: {
    'parent':parent
  },
  name: 'app',
  data () {
    return {
    }
  }
}
</script>

The parent component has a button click to update the data and the change is displayed in the component

Parent.vue:

<template>
    <div>
        <h2>Text Input</h2>
        <input v-model="input1"> {{ input1 }}

        <h2>Multi Checkbox</h2>
        <input type="checkbox" id="jack" value="Jack" v-model="input2">
        <label for="jack">Jack</label>
        <input type="checkbox" id="john" value="John" v-model="input2">
        <label for="john">John</label>
        <input type="checkbox" id="mike" value="Mike" v-model="input2">
        <label for="mike">Mike</label>
        <p>Checked names: <pre>{{ input2 }}</pre></p>

        <h2>Radio</h2>
        <input type="radio" id="one" value="One" v-model="input3">
        <label for="one">One</label>
        <br>
        <input type="radio" id="two" value="Two" v-model="input3">
        <label for="two">Two</label>
        <br>
        <span>Picked: {{ input3 }}</span>
        <h2>new stuff</h2>
        <button @click="getData()">Push Me</button>

        <p> The data is changing here: {{ allInputs }} </p>

        <child :all-inputs="allInputs"></child >
    </div>
</template>

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

export default{
    components: {
        'child':child 
    },
    data(){
        return{
            input1: '',
            input2: [],
            input3: '',
            allInputs: ''
        }
    },
    methods: {
        getData(){
            this.allInputs = {
                input1: this.input1,
                input2: this.input2,
                input3: this.input3
            }
        }
    }
}
</script>

But when I pass the data from the parent to a child, the data is not displayed on update:

Child.vue:

<template>
    <div >
        <p>{{ passedData }}</p>
    </div>
</template>

<script>

export default {
    props: ["allInputs"],
    data (){
        return{
            passedData: this.allInputs
        }
    }
}
</script>

CodePudding user response:

Instead of having passedData in your template like this:

<template>
    <div >
        <p>{{ passedData }}</p>
    </div>
</template>

Change it to:

<template>
    <div >
        <p>{{ allInputs }}</p>
    </div>
</template>

CodePudding user response:

Your child is not updating because you are using the local data property passedData in the template, not the props allInputs. If you will console the allInputs somewhere in the child component you will see that it is updating whenever the parent updates but as you are not using the prop directly so you are not seeing its reactivity. So, use props in your template instead of local data property, like this-

<p>{{ allInputs }}</p>

Not this-

<p>{{ passedData }}</p>

The approach you are trying to do is used when the child component wants to update the props passed by the parent but mutating parent props is erroneous because a child should not mutate (modify) the parent's state. So we usually assign props to a local data property and then mutate that data property, not props (same as you are doing). You can read more about this concept here.

  • Related