JAVASCRIPT
Implement Custom v-model on a Vue 3 Component
Discover how to create custom Vue 3 components that support `v-model` for two-way data binding, enabling cleaner form and input management.
// components/CustomInput.vue
<template>
<input
:value="modelValue"
@input="$emit('update:modelValue', $event.target.value)"
type="text"
placeholder="Enter text..."
/>
</template>
<script setup>
import { defineProps, defineEmits } from 'vue';
defineProps({
modelValue: { type: String, default: '' },
});
defineEmits(['update:modelValue']);
</script>
// Usage in a parent component (e.g., App.vue)
// <template>
// <div>
// <p>Parent Value: {{ myText }}</p>
// <CustomInput v-model="myText" />
// <CustomInput v-model:modelValue="anotherText" /> <!-- Explicit syntax for clarity -->
// <p>Another Value: {{ anotherText }}</p>
// </div>
// </template>
// <script setup>
// import { ref } from 'vue';
// import CustomInput from './components/CustomInput.vue';
// const myText = ref('Hello Vue!');
// const anotherText = ref('Two-way binding!');
// </script>
How it works: This snippet illustrates how to make a custom Vue 3 component compatible with `v-model`. For a component to support `v-model`, it must accept a `modelValue` prop and emit an `update:modelValue` event. The `CustomInput.vue` component defines `modelValue` as a prop to receive the value from the parent and emits `update:modelValue` with the new value whenever its internal input changes. This setup allows the parent component to use `v-model` directly on `CustomInput`, creating a clean and intuitive two-way data binding experience, similar to native HTML input elements.