Is it possible to use the value of a prop as the input's v-model?
I normally do the following when creating an input:
<template>
<form>
<input v-model="form.email" type="email"/>
</form>
</template>
<script>
export default {
data() {
return {
form: {
email: '',
}
}
}
}
</script>
But now I'm trying to achieve the following where this.myProp is used within the v-model without being displayed as a string on the input:
<template>
<form>
<input v-model="this.myProp" type="email"/>
</form>
</template>
<script>
export default {
props: ['myProp'] // myProp = form.email for example (to be handled in a parent component)
}
</script>
CodePudding user response:
Yes, but while using it in parent component. In child component you need to extract value
and @input
instead of using v-model
(v-model is shortcut for value=""
and @input
) Here is an example of input with label, error and hint in Vue 3 composition API.
BaseInput.vue
<template>
<div >
<label>{{ label }}</label>
<input v-bind="$attrs" :placeholder="label" :value="modelValue" @input="$emit('update:modelValue', $event.target.value)">
<span v-for="item of errors" >{{ item.value }}</span>
<span v-if="hint" >{{ hint }}</span>
</div>
</template>
<script setup>
defineProps({ label: String, modelValue: String | Number, errors: Array, hint: String })
defineEmits(['update:modelValue'])
</script>
Using v-bind="$attrs"
you target where attributes like type="email"
need to be applied in child component. If you don't do it, it will be added to the top level DOM element. In above scenario <div>
.
ParentComponent.vue
<BaseInput type="email" v-model="formData.email" :label="Email" :errors="formErrors.email"/>
CodePudding user response:
You can use computed prop and update v-model:
const app = Vue.createApp({
data() {
return {
form: {
email: '[email protected]',
}
}
},
})
app.component('child', {
template: `
<form>
<input v-model="model" type="email" />
</form>
`,
props: {
modelValue: String
},
emits: ['update:modelValue'],
computed: {
model: {
get() {
return this.modelValue
},
set(newValue) {
this.$emit('update:modelValue', newValue)
}
}
}
})
app.mount('#demo')
<script src="https://unpkg.com/vue@3/dist/vue.global.prod.js"></script>
<div id="demo">
{{ form.email }}
<child v-model="form.email"></child>
</div>