JAVASCRIPT
Implementing Custom `v-model` for Components with Multiple Props in Vue 3
Learn to create flexible custom `v-model` bindings in Vue 3 components, enabling seamless two-way data binding for multiple properties using `defineModel`.
<script setup>
import { ref } from 'vue';
// Child component definition (MyCustomInput.vue)
const MyCustomInput = {
setup() {
// defineModel is a compiler macro (Vue 3.4+)
// 'modelValue' is the default name for v-model's primary prop
const model = defineModel();
const checked = defineModel('checked', { type: Boolean, default: false });
return { model, checked };
},
template: `
<div style="border: 1px solid #eee; padding: 10px; margin-bottom: 10px;">
<label>Text Input (modelValue):
<input type="text" :value="model" @input="model = $event.target.value" />
</label>
<p>Current Text: {{ model }}</p>
<label>Checkbox (checked):
<input type="checkbox" :checked="checked" @change="checked = $event.target.checked" />
</label>
<p>Checkbox Status: {{ checked ? 'Checked' : 'Unchecked' }}</p>
</div>
`
};
// Parent component using MyCustomInput
const parentText = ref('Initial Text');
const parentChecked = ref(true);
</script>
<template>
<div>
<h3>Parent Component</h3>
<p>Parent Text: {{ parentText }}</p>
<p>Parent Checkbox: {{ parentChecked }}</p>
<MyCustomInput v-model="parentText" v-model:checked="parentChecked" />
<p style="margin-top: 20px; font-style: italic;">
Child component uses `defineModel()` to expose multiple v-model bindings.
</p>
</div>
</template>
How it works: This snippet demonstrates how to create a custom input component that supports multiple `v-model` bindings using Vue 3.4+'s `defineModel` macro. The `MyCustomInput` component uses `defineModel()` for its primary text input and `defineModel('checked')` for a secondary checkbox. This allows the parent component to use `v-model="parentText"` and `v-model:checked="parentChecked"` for clean, two-way data binding with the child's internal state, abstracting away the explicit `prop` and `emit` pattern.