I try to bind child input value to the parent value. I pass value searchText
from a Parent component to a Child component as prop :valueProp
. There I assign it to property value: this.valueProp
and bind input:
<input type="text" :value="value" @input="$emit('changeInput', $event.target.value)" />
The problem is that input doesn't work with such setup, nothing displays in input, but parent searchText
and valueProp
in child update only with the last typed letter; value
in child doesn't update at all, though it is set to equal to searchText
.
If I remove :value="value"
in input, all will work fine, but value
in child doesn't get updated along with parent's searchText
.
I know that in such cases it's better to use v-model
, but I want to figure out the reason behind such behavior in that case.
I can't understand why it works in such way and value
in child component doesn't update with parent's searchText
. Can you please explain why it behaves in that way?
Link to Sanbox: Sandbox
Parent:
<template>
<div>
<Child :valueProp="searchText" @changeInput="changeInput" />
<p>parent {{ searchText }}</p>
</div>
</template>
<script>
import Child from "./Child.vue";
export default {
name: "Parent",
components: { Child },
data() {
return {
searchText: "",
};
},
methods: {
changeInput(data) {
console.log(data);
this.searchText = data;
},
},
};
</script>
Child:
<template>
<div>
<input type="text" :value="value" @input="$emit('changeInput', $event.target.value)" />
<p>value: {{ value }}</p>
<p>child: {{ valueProp }}</p>
</div>
</template>
<script>
export default {
emits: ["changeInput"],
data() {
return {
value: this.valueProp,
};
},
props: {
valueProp: {
type: String,
required: true,
},
},
};
</script>
CodePudding user response:
You set the value
in your Child
component only once by instantiating.
In the data()
you set the initial value of your data properties:
data() {
return {
value: this.valueProp,
};
},
Since you don't use v-model
, the value
will never be updated.
You have the following options to fix it:
- The best one is to use
v-model
withvalue
in theChild.vue
<input
type="text"
v-model="value"
- update
value
using watcher
watch: {
valueProp(newValue) {
this.value = newValue;
}
},
- use a computed property for
value
instead of data property
computed: {
value() {return this.valueProp;}
}
Respect for creating the sandbox!
CodePudding user response:
You are overwriting the local value every time the value changes
data() {
return {
value: this.valueProp, // Don't do this
};
},
Bind directly to the prop:
<input ... :value="valueProp" ... />