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.