In Vue 3, when emitting an event from child to parent to update refs and subsequently refresh the props of the child the form control flow breaks i.e. tabindex or [tab]
ing between fields doesn’t work. My code is roughly setup as follows:
Parent.vue
<script setup>
import { ref } from 'vue'
import Child from './Child.vue'
const connection = ref(null)
const change = (updated) => {
connection.value = updated
}
</script>
<template>
<Child :connection="connection" @update="change" />
</template>
Child.vue
<script setup>
import { ref } from 'vue'
const props = defineProps({
connection: Object,
})
const emit = defineEmits(['update'])
const a = ref(props.connection?.a)
const b = ref(props.connection?.b)
const c = ref(props.connection?.c)
const update = () => {
emit('update', {
a: a.value,
b: b.value,
c: c.value,
})
}
</script>
<template>
<input v-model="a" @blur="update" />
<input v-model="b" @blur="update" />
<input v-model="c" @blur="update" />
</template>
I’m guessing due to it being an object that it breaks the the flow as it re-renders the whole child and loses focus. Question is how can I update the object and keep the focus the same?
Side note: I don’t want to emit individual model value events like below because I don’t want the parent to have to deal with every property since I’m creating several distinct Child
vues for different forms.
<script setup>
defineProps({
firstName: String,
lastName: String
})
defineEmits(['update:firstName', 'update:lastName'])
</script>
<template>
<input
type="text"
:value="firstName"
@input="$emit('update:firstName', $event.target.value)"
/>
<input
type="text"
:value="lastName"
@input="$emit('update:lastName', $event.target.value)"
/>
</template>
This would lead to a parent like this and I’ll end up having to handle a-z
...
<Child
v-model:a="connection.a"
v-model:b="connection.b"
v-model:c="connection.c"
...
2
Answers
The answer from @boussadjra-brahim was useful and led me to this solution. I preferred the code below as I could transform data going back and forth between parent and child as illustrated by the split-join on ref
c
.Parent component :
Try to simplify the Child component state with a writable computed that get the prop values and emit the new values when it’s mutated :
Parent component :
LIVE DEMO