I have a form where I need to update multiple other form fields when another field is updated. For example, I have a contact name and depending on the contact name, I need to update the values of the email and phone.
<template>
<custom-input :value="contact.name" @input="event => contact.name = event.target.value" />
<custom-input :value="contact.phone" @input="event => contact.phone = event.target.value" />
<custom-input :value="contact.email" @input="event => contact.email = event.target.value" />
</template>
<script>
...
props: {
contact: {
type: Object,
required: true
}
},
watch:
"contact.name": function(value) {
if (this.contact.name === "john") {
this.contact.email = "[email protected]"
this.contact.phone = "1111111111"
} else if (this.contact.name === "ed") {
this.contact.email = "[email protected]"
this.contact.phone = "2222222222"
}
}
}
...
</script>
I understand that Vue doesn't like this because it separates the DOM from the data model. My first thought was to use $refs but those are read only. What's the right way to do this?
Another thought I had was to set the value of name and phone to computed properties. The problem with that is that it doesn't get watched on the form in the parent component.
This might also tie in with my misunderstanding of "two-way" binding. I've always reasoned that the form is one way, and the data within the component's script is the other which it is not. So, what's the other way?
A final thought I have is that I might have to emit an event instead?
<template>
<custom-input :value="contact.name" @input="event => contact.name = event.target.value" />
<custom-input ref="phone" :value="contact.phone" @input="event => contact.phone = event.target.value" />
<custom-input ref="email" :value="contact.email" @input="event => contact.email = event.target.value" />
</template>
<script>
...
props: {
contact: {
type: Object,
required: true
}
},
watch:
"contact.name": function(value) {
if (this.contact.name === "john") {
this.$refs.email.$emit("input", "[email protected]")
this.$refs.phone.$emit("input", "111111111111")
} else if (this.contact.name === "ed") {
this.$refs.email.$emit("input", "[email protected]")
this.$refs.phone.$emit("input", "222222222222")
}
}
}
That doesn't seem to work either. Bummer.
Edit
Fixed syntax errors
Edit 2
Showed that input was actually a separate child component
:valueand@input(just usev-model), I don't see any issue with what you're doing here. Maybe I misunderstood your question?v-modelcan (and should) be used here, but since we're dealing with a custom component, you may not be receiving the native event object for theinputevent that it emits. Can you confirm that?Error in v-on handler: "TypeError: Cannot read property 'value' of undefined"