JAVASCRIPT
Building Reusable Input Components with Vue 3 Custom v-model
Learn to create custom input components in Vue 3 that seamlessly integrate with `v-model`, simplifying two-way data binding for enhanced reusability and developer experience.
<!-- ParentComponent.vue -->
<template>
<div>
<h1>Parent Component</h1>
<p>Message from custom input: {{ myMessage }}</p>
<CustomInput v-model="myMessage" />
<CustomInput label="Enter a number" v-model.number="myNumber" />
<p>Number: {{ myNumber }}</p>
</div>
</template>
<script setup>
import { ref } from 'vue';
import CustomInput from './components/CustomInput.vue';
const myMessage = ref('Hello Vue!');
const myNumber = ref(0);
</script>
<!-- CustomInput.vue -->
<template>
<div>
<label v-if="label">{{ label }}: </label>
<input
:value="modelValue"
@input="$emit('update:modelValue', $event.target.value)"
/>
</div>
</template>
<script setup>
import { defineProps, defineEmits } from 'vue';
defineProps({
modelValue: {
type: [String, Number],
default: ''
},
label: {
type: String,
default: ''
}
});
defineEmits(['update:modelValue']);
</script>
How it works: This snippet illustrates how to create a custom input component that supports `v-model` in Vue 3. The `CustomInput` component expects a `modelValue` prop and emits an `update:modelValue` event when its internal input changes. The parent component then uses `v-model="myMessage"` on `CustomInput`, which Vue automatically expands to `:modelValue="myMessage" @update:modelValue="myMessage = $event"`, providing seamless two-way data binding. It also demonstrates how to apply `v-model` modifiers like `.number` when defining the `modelValue` prop.