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.