← Back to all snippets
VUE

Custom `v-model` for Component Value Binding

Implement `v-model` on your custom Vue 3 components to enable two-way data binding, making them intuitive and reusable for form inputs and other interactive elements.

// MyCustomInput.vue
<template>
  <input
    :value="modelValue"
    @input="$emit('update:modelValue', $event.target.value)"
    type="text"
  />
</template>

<script setup>
import { defineProps, defineEmits } from 'vue';

defineProps({
  modelValue: String // Prop for v-model's value
});

defineEmits(['update:modelValue']); // Emit event for v-model update
</script>

// App.vue
<template>
  <div>
    <p>Message: {{ myMessage }}</p>
    <MyCustomInput v-model="myMessage" />
    <br />
    <p>Username: {{ username }}</p>
    <MyAdvancedInput v-model:username="username" v-model:email="email" />
    <p>Email: {{ email }}</p>
  </div>
</template>

<script setup>
import { ref } from 'vue';
import MyCustomInput from './MyCustomInput.vue';
import MyAdvancedInput from './MyAdvancedInput.vue'; // For multiple v-model

const myMessage = ref('Hello Vue!');
const username = ref('JohnDoe');
const email = ref('[email protected]');
</script>

// MyAdvancedInput.vue (Example for multiple v-model bindings)
<template>
  <div>
    <label>Username:</label>
    <input
      :value="username"
      @input="$emit('update:username', $event.target.value)"
      type="text"
    />
    <label>Email:</label>
    <input
      :value="email"
      @input="$emit('update:email', $event.target.value)"
      type="email"
    />
  </div>
</template>

<script setup>
import { defineProps, defineEmits } from 'vue';

defineProps({
  username: String,
  email: String
});

defineEmits(['update:username', 'update:email']);
</script>
How it works: This snippet shows how to implement custom `v-model` functionality on your own Vue 3 components. By default, `v-model` uses a `modelValue` prop and an `update:modelValue` event. A custom component needs to declare `modelValue` as a prop and emit `update:modelValue` with the new value when its internal state changes. The example also demonstrates how to use multiple `v-model` bindings on a single component by specifying custom argument names (e.g., `v-model:username`). This pattern is essential for creating robust and user-friendly reusable form elements.

Need help integrating this into your project?

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

Hire DigitalCodeLabs