JAVASCRIPT

Implementing Custom `v-model` for Reusable Form Components in Vue 3

Extend Vue 3's `v-model` directive to create custom, reusable input components, simplifying form data binding and component design.

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

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

defineProps({
  modelValue: {
    type: String,
    default: ''
  },
  label: {
    type: String,
    required: true
  }
});

defineEmits(['update:modelValue']);
</script>

<style scoped>
label {
  display: block;
  margin-bottom: 15px;
}
input {
  padding: 8px;
  border: 1px solid #ccc;
  border-radius: 4px;
  width: 200px;
}
</style>

// ParentComponent.vue
<template>
  <div>
    <h2>User Profile</h2>
    <CustomInput label="Your Name" v-model="userName" />
    <CustomInput label="Your Email" v-model="userEmail" />
    <p>Name: {{ userName }}</p>
    <p>Email: {{ userEmail }}</p>
  </div>
</template>

<script setup>
import { ref } from 'vue';
import CustomInput from './CustomInput.vue';

const userName = ref('John Doe');
const userEmail = ref('[email protected]');
</script>
How it works: This snippet demonstrates how to implement `v-model` on a custom Vue 3 component. The `CustomInput.vue` component accepts a `modelValue` prop and emits an `update:modelValue` event whenever its internal input changes. This specific prop and event naming convention allows the parent component (`ParentComponent.vue`) to use `v-model="userName"` directly on `CustomInput`, abstracting away the explicit prop passing and event listening, making custom form components highly reusable and intuitive to work with.

Need help integrating this into your project?

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

Hire DigitalCodeLabs