DullishTech - Web Development and Programming

Last updated on

Easy Custom Input with defineModel in VueJS 3

Vue 3.3 introduces a new compiler macro called defineModel that makes it easy to create custom input components with two way data binding. In this article, we will see how to create a custom input component with two way data binding in VueJS 3 using defineModel. Prior to Vue 3.3, we had to use v-model and emit prop update:modelValue to achevie two way data binding for a custom component. Let’s see how to do it with defineModel.

Enable defineModel

Starting Vue 3.4 defineModel is enabled out of the box and no changes to config are required.

If you are using Vue 3.3,

defineModel macro is still experimental and is not enabled by default and requires an explicit opt-in.To enable defineModel, you need to add the following code in vite.config.ts file

export default {
  plugins: [
    vue({
      script: {
        defineModel: true,
      },
    }),
  ],
};

Enable defineModel in NuxtJS 3

Depending on version of NuxtJS you are using, you may need to explicitly enable defineModel. If you have Vue 3.4 as peer dependency, defineModel is enabled by default.

If you are using NuxtJS 3 with Vue 3.3, you can enable defineModel by adding the following code in nuxt.config.ts file.

export default defineNuxtConfig({
  vite: {
    vue: {
      script: {
        defineModel: true,
      },
    },
  },
});

Using defineModel

Let’s create a custom component called ColorPicker that allow our user to select one of the available colors. We will use defineModel to create this custom component.

<script setup lang="ts">
const inputValue = defineModel<string>();
</script>

<template>
  <div class="flex rounded-md">
    <a href="#" class="border p-2 px-3" @click="inputValue = 'red'">Red</a>
    <a href="#" class="border p-2 px-3" @click="inputValue = 'green'">Green</a>
    <a href="#" class="border p-2 px-3" @click="inputValue = 'blue'">Blue</a>
  </div>
</template>

In the above code, we have defined a inputValue variable using defineModel. Vue will automatically create a modelValue prop and update:modelValue event for us. We can use inputValue variable to set the value of the input and it will automatically update the parent component when the value changes.

Using the custom component

Let’s use the custom component we created above in our parent component.

<script setup lang="ts">
import ColorPicker from "./ColorPicker.vue";
const color = ref<string>("red");
</script>

<template>
  <ColorPicker v-model="color" />
  <div>Selected Color: {{ color }}</div>
</template>

defineModel is a great addition to VueJS 3 and makes it easy to create custom input components with two way data binding. Note that this is still an experimental feature and is not enabled by default. It may change in future versions of VueJS It is available out of the box starting from Vue 3.4, you can read more about this feature in the official RFC.

Related Posts