JAVASCRIPT
Implementing Custom `v-model` for Form Components in Vue 3
Learn to make your custom Vue 3 components fully compatible with `v-model`, enabling two-way data binding for various input types and complex controls.
// CustomInput.vue
<template>
<input
type="text"
:value="modelValue"
@input="$emit('update:modelValue', $event.target.value)"
class="custom-input"
placeholder="Enter text..."
/>
</template>
<script setup>
import { defineProps, defineEmits } from 'vue';
const props = defineProps({
modelValue: {
type: String,
default: ''
}
});
const emit = defineEmits(['update:modelValue']);
</script>
<style scoped>
.custom-input {
padding: 8px;
border: 1px solid #ccc;
border-radius: 4px;
width: 100%;
box-sizing: border-box;
}
</style>
// MyForm.vue
<template>
<div>
<h2>My Form</h2>
<p>User Name: {{ username }}</p>
<CustomInput v-model="username" />
<p>Search Query: {{ searchQuery }}</p>
<!-- Customizing the v-model argument -->
<CustomInput v-model:searchQuery="searchQuery" />
<p>Active Status: {{ isActive }}</p>
<!-- For boolean/checkbox-like controls -->
<CustomCheckbox v-model="isActive" label="Is Active" />
</div>
</template>
<script setup>
import { ref } from 'vue';
import CustomInput from './CustomInput.vue';
import CustomCheckbox from './CustomCheckbox.vue'; // Assume this also uses v-model
const username = ref('John Doe');
const searchQuery = ref('');
const isActive = ref(true);
</script>
// CustomCheckbox.vue (Example for boolean v-model)
<template>
<label>
<input
type="checkbox"
:checked="modelValue"
@change="$emit('update:modelValue', $event.target.checked)"
/>
{{ label }}
</label>
</template>
<script setup>
import { defineProps, defineEmits } from 'vue';
const props = defineProps({
modelValue: {
type: Boolean,
default: false
},
label: {
type: String,
default: ''
}
});
const emit = defineEmits(['update:modelValue']);
</script>
How it works: This snippet details how to implement custom `v-model` functionality for your own Vue 3 components, allowing them to support two-way data binding similar to native input elements. By accepting a `modelValue` prop and emitting an `update:modelValue` event, components can seamlessly integrate with the `v-model` directive. It also shows how to customize the `v-model` argument for multiple bindings on a single component.