I just found out that in Vue3, v-model
is not working responsively / reactively with child Component
.
This code will update the username
data
<template> <div> <input type="text" v-model="username" placeholder="Insert your username" /> <p>{{ username }}</p> </div> </template> <script> // Home.vue export default { name: 'Home', data() { return { username: 'admin' } } } </script>
If I type something in the input
, the username
data will change too.
But, when I use Component
like this example:
<template> <input type="text" :class="'input-text ' + additionalClass" :placeholder="placeholder" /> </template> <script> // InputText.vue import { defineComponent } from "vue" export default defineComponent({ name: 'InputText', props: { placeholder: { type: String, default: '' }, additionalClass: { type: String, default: '' } } }) </script>
Then I updated my code to use the Component
.
Note: The Component
is registered successfully.
<template> <div> <input-text v-model="username" :placeholder="`Insert your username`" /> <p>{{ username }}</p> </div> </template> <script> // Home.vue export default { name: 'Home', data() { return { username: 'admin' } } } </script>
When I type something, the username
data not updated, different with the previous one.
Is there any solution or at least reference of what I’m trying to achieve?
Advertisement
Answer
You can’t expect v-model
to implicitly update the underlying element for you. In other words, you’ll still need to handle that within the component itself and expose modelValue
as a prop for this to really work. Something like that:
<template> <input type="text" @input="onChanged" :value="modelValue" :class="'input-text ' + additionalClass" :placeholder="placeholder" /> </template> <script> // InputText.vue import { defineComponent } from "vue" export default defineComponent({ name: 'InputText', emits: ['update:modelValue'], props: { modelValue: String, placeholder: { type: String, default: '' }, additionalClass: { type: String, default: '' } }, setup(props, { emit }) { function onChanged(e) { emit('update:modelValue', e.currentTarget.value); } return { onChanged } } }) </script>