DEV Community

Ibrahim
Ibrahim

Posted on

How to Make a Vue Component Work with v-model

In Vue.js version 3.5, you can make a Vue component work with v-model using the defineModel macro. For example:

<!-- BaseInput.vue -->
<script setup>
const value = defineModel();
</script>
<template>
  <input type="text" v-model="value" />
</template>

<!-- App.vue -->
<script setup>
import { ref } from "vue";
import BaseInput from "./components/BaseInput.vue";

const value = ref("");
</script>
<template>
  <BaseInput v-model="value" />
</template>
Enter fullscreen mode Exit fullscreen mode

In Vue.js versions below 3.5, the defineModel macro does not exist. Instead, you can use the modelValue prop to receive the v-model value, and emit the update:modelValue event to update it.

<!-- BaseInput.vue -->
<script setup>
const props = defineProps(["modelValue"]);
const emit = defineEmits(["update:modelValue"]);
</script>
<template>
  <input
    type="text"
    :value="props.modelValue"
    @input="emit('update:modelValue', $event.target.value)"
  />
</template>

<!-- App.vue -->
<script setup>
import { ref } from "vue";
import BaseInput from "./components/BaseInput.vue";

const value = ref("");
</script>
<template>
  <BaseInput v-model="value" />
</template>
Enter fullscreen mode Exit fullscreen mode

Alternatively, you can use a computed property, where the getter returns props.modelValue, and the setter emits the update:modelValue event.

<!-- BaseInput.vue -->
<script setup>
import { computed } from "vue";
const props = defineProps(["modelValue"]);
const emit = defineEmits(["update:modelValue"]);

const value = computed({
  get: () => props.modelValue,
  set: (newValue) => emit("update:modelValue", newValue),
});
</script>
<template>
  <input type="text" v-model="value" />
</template>

<!-- App.vue -->
<script setup>
import { ref } from "vue";
import BaseInput from "./components/BaseInput.vue";

const value = ref("");
</script>
<template>
  <BaseInput v-model="value" />
</template>
Enter fullscreen mode Exit fullscreen mode

Top comments (0)