JAVASCRIPT
Custom `v-model` with Multiple Properties
Extend Vue 3's `v-model` to bind multiple properties simultaneously on a custom input component, enabling more flexible and reusable custom form elements.
// CustomInput.vue
<template>
<div class="custom-input-group">
<label for="username">Username:</label>
<input
id="username"
type="text"
:value="userName"
@input="$emit('update:userName', $event.target.value)"
/>
<label for="email">Email:</label>
<input
id="email"
type="email"
:value="userEmail"
@input="$emit('update:userEmail', $event.target.value)"
/>
<button @click="clearInputs">Clear Both</button>
</div>
</template>
<script setup>
import { defineProps, defineEmits } from 'vue';
// Define props for each v-model binding
const props = defineProps({
userName: String,
userEmail: String,
});
// Define emits for each v-model update
const emit = defineEmits(['update:userName', 'update:userEmail']);
const clearInputs = () => {
emit('update:userName', '');
emit('update:userEmail', '');
};
</script>
<style scoped>
.custom-input-group {
display: flex;
flex-direction: column;
gap: 10px;
padding: 20px;
border: 1px solid #ccc;
border-radius: 8px;
max-width: 300px;
margin: 20px auto;
}
label {
font-weight: bold;
}
input {
padding: 8px;
border: 1px solid #ddd;
border-radius: 4px;
}
button {
padding: 10px 15px;
background-color: #007bff;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
margin-top: 10px;
}
button:hover {
background-color: #0056b3;
}
</style>
/*
// Usage in a parent component (App.vue):
<template>
<div id="app">
<h1>Parent Component</h1>
<p>Current Username: {{ userNameRef }}</p>
<p>Current Email: {{ userEmailRef }}</p>
<hr/>
<CustomInput
v-model:userName="userNameRef"
v-model:userEmail="userEmailRef"
/>
</div>
</template>
<script setup>
import { ref } from 'vue';
import CustomInput from './CustomInput.vue';
const userNameRef = ref('JohnDoe');
const userEmailRef = ref('[email protected]');
</script>
*/
How it works: This snippet illustrates how to create a custom component that supports multiple `v-model` bindings in Vue 3. By defining props with names like `propName` and emitting corresponding events named `update:propName`, a component can effectively use `v-model:propName='value'` syntax. This pattern allows for encapsulating complex input logic within a single component while maintaining a clean and declarative API for its parent components, making custom form controls more powerful and intuitive to use.