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.

Need help integrating this into your project?

Our team of expert developers can help you build your custom application from scratch.

Hire DigitalCodeLabs