JAVASCRIPT
Build a Custom Vue 3 Input Component with `v-model` Support
Learn to create a reusable custom input component in Vue 3 that fully supports `v-model` for two-way data binding, enhancing form flexibility and reusability.
// components/MyCustomInput.vue
<template>
<label>
{{ label }}:
<input
type="text"
:value="modelValue"
@input="$emit('update:modelValue', $event.target.value)"
class="custom-input"
/>
</label>
</template>
<script setup>
import { defineProps, defineEmits } from 'vue';
// Define props, including 'modelValue' for v-model binding
defineProps({
modelValue: { type: String, default: '' },
label: { type: String, default: 'Input' }
});
// Define emits, including 'update:modelValue' for v-model binding
defineEmits(['update:modelValue']);
</script>
<style scoped>
.custom-input {
padding: 8px;
border: 1px solid #ccc;
border-radius: 4px;
width: 100%;
max-width: 300px;
}
</style>
// App.vue (Usage)
<template>
<div>
<h1>Custom Input Example</h1>
<MyCustomInput v-model="userName" label="Your Name" />
<p>You typed: {{ userName }}</p>
<MyCustomInput v-model="userEmail" label="Your Email" />
<p>Your email: {{ userEmail }}</p>
</div>
</template>
<script setup>
import { ref } from 'vue';
import MyCustomInput from './components/MyCustomInput.vue';
const userName = ref('John Doe');
const userEmail = ref('');
</script>
How it works: This snippet illustrates how to create a custom input component that supports Vue 3's `v-model` directive. For a component to work with `v-model`, it needs to accept a `modelValue` prop (by default) and emit an `update:modelValue` event when its internal value changes. This allows for two-way data binding between the parent component's data and the custom input, making custom form elements as easy to use as native ones. The `label` prop is added to make the custom input more versatile.