I am working on a form that requires updating multiple other fields when one field is updated. For instance, I have a contact name field and depending on the name entered, I need to update the email and phone number fields as well.
<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 = "<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="244e4b4c4a644149454d480a474b49">[email protected]</a>"
this.contact.phone = "1111111111"
} else if (this.contact.name === "ed") {
this.contact.email = "<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="6e0b0a2e0b030f0702400d0103">[email protected]</a>"
this.contact.phone = "2222222222"
}
}
}
...
</script>
It appears that Vue dislikes this approach because it segregates the DOM from the data model. Initially, I thought about using $refs
, but those are only readable. What would be the correct method for accomplishing this task?
Another idea I had was to assign computed properties to the values of name
and phone
. However, this causes an issue since it will not trigger any changes in the parent component's form.
This problem may also stem from my misunderstanding of "two-way" binding. I always believed that the form represents one direction while the data within the component's script serves as the other, which is evidently not the case. So, what is the alternative?
A final consideration I have is emitting 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", "<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="d6bcb9beb896b3bb7bdbaf8b5bbb9">[email protected]</a>")
this.$refs.phone.$emit("input", "111111111111")
} else if (this.contact.name === "ed") {
this.$refs.email.$emit("input", "<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="284d4c684d45494144064b4745">[email protected]</a>")
this.$refs.phone.$emit("input", "222222222222")
}
}
}
Unfortunately, this solution does not seem to work either. Quite disappointing.
Edit
Syntax errors fixed.
Edit 2
Demonstrated that input
is actually a separate child component.