JAVASCRIPT
Implementing Custom `v-model` for Reusable Form Components in Vue 3
Extend Vue 3's `v-model` directive to create custom, reusable input components, simplifying form data binding and component design.
// CustomInput.vue
<template>
<label>
{{ label }}:
<input
type="text"
:value="modelValue"
@input="$emit('update:modelValue', $event.target.value)"
/>
</label>
</template>
<script setup>
import { defineProps, defineEmits } from 'vue';
defineProps({
modelValue: {
type: String,
default: ''
},
label: {
type: String,
required: true
}
});
defineEmits(['update:modelValue']);
</script>
<style scoped>
label {
display: block;
margin-bottom: 15px;
}
input {
padding: 8px;
border: 1px solid #ccc;
border-radius: 4px;
width: 200px;
}
</style>
// ParentComponent.vue
<template>
<div>
<h2>User Profile</h2>
<CustomInput label="Your Name" v-model="userName" />
<CustomInput label="Your Email" v-model="userEmail" />
<p>Name: {{ userName }}</p>
<p>Email: {{ userEmail }}</p>
</div>
</template>
<script setup>
import { ref } from 'vue';
import CustomInput from './CustomInput.vue';
const userName = ref('John Doe');
const userEmail = ref('[email protected]');
</script>
How it works: This snippet demonstrates how to implement `v-model` on a custom Vue 3 component. The `CustomInput.vue` component accepts a `modelValue` prop and emits an `update:modelValue` event whenever its internal input changes. This specific prop and event naming convention allows the parent component (`ParentComponent.vue`) to use `v-model="userName"` directly on `CustomInput`, abstracting away the explicit prop passing and event listening, making custom form components highly reusable and intuitive to work with.