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.

Need help integrating this into your project?

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

Hire DigitalCodeLabs