JAVASCRIPT

Two-Way Data Binding on Custom Components with Vue 3 `v-model`

Understand how to implement and customize `v-model` on your own Vue 3 components, allowing two-way data binding with prop-event pairs and custom logic.

// CustomTextInput.vue
<template>
  <input 
    type="text" 
    :value="processedModelValue" 
    @input="emitValue" 
    :placeholder="placeholder"
  />
</template>

<script setup>
import { computed } from 'vue';

const props = defineProps({
  modelValue: String, // Default prop for v-model
  placeholder: {
    type: String,
    default: 'Enter text'
  }
});

const emit = defineEmits(['update:modelValue']); // Default event for v-model

// A computed property to process the incoming modelValue before rendering
// or to format it for display (e.g., capitalize first letter)
const processedModelValue = computed(() => {
  return props.modelValue ? props.modelValue.toUpperCase() : '';
});

function emitValue(event) {
  // Emit the event with the new value, optionally transforming it
  emit('update:modelValue', event.target.value);
}
</script>

// App.vue (Parent Component)
<template>
  <div>
    <p>Parent Value: {{ message }}</p>
    <CustomTextInput v-model="message" placeholder="Type something..."/>
    <CustomTextInput v-model="anotherMessage" placeholder="Another input..."/>
    <p>Another Value: {{ anotherMessage }}</p>
  </div>
</template>

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

const message = ref('hello vue');
const anotherMessage = ref('world');
</script>
How it works: This snippet demonstrates how to implement `v-model` on a custom Vue 3 component. By default, `v-model` on a component binds to a `modelValue` prop and listens for an `update:modelValue` event. The `CustomTextInput` component defines `modelValue` as a prop and uses `defineEmits` to declare the `update:modelValue` event. A computed property `processedModelValue` is used to apply custom logic (e.g., converting to uppercase) to the displayed value, while `emitValue` handles updating the parent's bound data. This pattern allows for flexible and reusable form controls with two-way data binding.

Need help integrating this into your project?

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

Hire DigitalCodeLabs