JAVASCRIPT
Custom `v-model` Implementation in Vue 3
Discover how to implement `v-model` on your custom Vue 3 components, allowing for two-way data binding similar to native input elements.
// components/CustomInput.vue
<template>
<input
:value="modelValue"
@input="$emit('update:modelValue', $event.target.value)"
type="text"
class="custom-input"
/>
</template>
<script setup>
import { defineProps, defineEmits } from 'vue';
defineProps({
modelValue: String, // Vue 3 default prop for v-model
});
defineEmits(['update:modelValue']); // Vue 3 default event for v-model
</script>
<style scoped>
.custom-input {
padding: 8px;
border: 1px solid #ccc;
border-radius: 4px;
}
</style>
// App.vue (Parent Component)
<template>
<div>
<p>Message: {{ message }}</p>
<CustomInput v-model="message" />
<p>Another message: {{ anotherMessage }}</p>
<CustomInput v-model="anotherMessage" />
</div>
</template>
<script setup>
import { ref } from 'vue';
import CustomInput from './components/CustomInput.vue';
const message = ref('Hello Vue!');
const anotherMessage = ref('Two-way binding works!');
</script>
How it works: This snippet shows how to enable `v-model` on a custom Vue 3 component. In Vue 3, `v-model` on a component is syntactic sugar for binding a `modelValue` prop and listening for an `update:modelValue` event. The `CustomInput` component defines a `modelValue` prop to receive the value from the parent and emits an `update:modelValue` event whenever its internal input changes. This allows the parent component to use `v-model="message"` for seamless two-way data binding, making custom components behave just like native form elements.