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?
with Vue3 script setup syntax
<template>
<input type="text" v-model="val" @input="handleInput">
</template>
<script setup>
import {ref, defineProps, defineEmits, watch} from 'vue'
const props = defineProps({
modelValue: {
type: String,
default: ''
},
})
const emit = defineEmits(['update:modelValue'])
const val = ref('')
watch(() => props.modelValue, nVal => val.value = nVal, {
immediate: true
})
const handleInput = () => emit('update:modelValue', val.value)
</script>
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>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With