JAVASCRIPT

Custom `v-model` for Reusable Vue 3 Components

Learn to implement a custom `v-model` on your own Vue 3 components using `defineModel` (or `modelValue` prop and `update:modelValue` event for older setups), creating intuitive two-way data binding.

// components/CustomInput.vue
// <template>
//   <label>{{ label }}:
//     <input
//       :type="type"
//       :value="modelValue"
//       @input="$emit('update:modelValue', $event.target.value)"
//       class="custom-input"
//     />
//   </label>
// </template>
//
// <script setup>
// // For Vue 3.4+ using defineModel is preferred
// // const modelValue = defineModel();
// // defineProps({
// //   label: String,
// //   type: {
// //     type: String,
// //     default: 'text'
// //   }
// // });

// // For Vue 3.0-3.3
// defineProps({
//   modelValue: [String, Number], // The default prop name for v-model
//   label: String,
//   type: {
//     type: String,
//     default: 'text'
//   }
// });

// defineEmits(['update:modelValue']); // The default event name for v-model updates
// </script>
//
// <style scoped>
// .custom-input {
//   border: 1px solid #ccc;
//   padding: 8px;
//   border-radius: 4px;
// }
// </style>

// App.vue
// <template>
//   <div>
//     <CustomInput label="Your Name" v-model="userName" />
//     <p>Hello, {{ userName }}</p>
//
//     <CustomInput label="Your Age" type="number" v-model.number="userAge" />
//     <p>Age: {{ userAge }}</p>
//   </div>
// </template>
//
// <script setup>
// import { ref } from 'vue';
// import CustomInput from './components/CustomInput.vue';
//
// const userName = ref('John Doe');
// const userAge = ref(30);
// </script>
How it works: This snippet details how to implement `v-model` on custom components in Vue 3, enabling intuitive two-way data binding. The `CustomInput` component accepts a `modelValue` prop (the default name for `v-model`) and emits an `update:modelValue` event whenever its internal value changes. This convention allows parent components to use `v-model` directly on `CustomInput`, abstracting away the explicit prop passing and event listening. For Vue 3.4+, `defineModel()` provides a more streamlined approach.

Need help integrating this into your project?

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

Hire DigitalCodeLabs