JAVASCRIPT
Custom `v-model` for Complex Vue 3 Components
Master creating custom inputs in Vue 3 by implementing `v-model` for two-way data binding, enabling your components to behave just like native form elements.
<!-- src/components/CustomInput.vue -->
<template>
<div style="border: 1px solid #ccc; padding: 10px; border-radius: 5px;">
<label :for="id">{{ label }}:</label>
<input
type="text"
:id="id"
:value="modelValue"
@input="$emit('update:modelValue', $event.target.value)"
placeholder="Enter text..."
/>
<p>Current Value: <em>{{ modelValue }}</em></p>
</div>
</template>
<script setup>
import { defineProps, defineEmits } from 'vue';
const props = defineProps({
modelValue: String,
label: {
type: String,
default: 'Custom Input'
},
id: {
type: String,
default: () => `custom-input-${Math.random().toString(36).substr(2, 9)}`
}
});
const emit = defineEmits(['update:modelValue']);
</script>
<!-- src/App.vue (or parent component) -->
<template>
<div>
<h1>Parent Component</h1>
<p>Parent Data: {{ parentData }}</p>
<CustomInput v-model="parentData" label="Your Name" />
<CustomInput v-model="anotherData" label="Your Email" />
</div>
</template>
<script setup>
import { ref } from 'vue';
import CustomInput from './components/CustomInput.vue';
const parentData = ref('Initial Value');
const anotherData = ref('[email protected]');
</script>
How it works: In Vue 3, `v-model` on a component is syntactic sugar for passing a `modelValue` prop and listening for an `update:modelValue` event. This snippet demonstrates how to implement `v-model` for a custom input component. The child component receives the value via `modelValue` prop and emits an `update:modelValue` event whenever its internal value changes. This allows the parent component to use `v-model` for seamless two-way data binding, making custom inputs as intuitive to use as native ones.