The defineModel macro from Vue 3.3
Say goodbye to the boilerplates 👋
With the introduction of the defineModel
macro in Vue 3.3, we can now define a model in a single line of code. Let's look at how previously we would define a model.
For the sake of this example, let's say we have a Counter
component that we want to use in our App
component. We want to be able to pass in a count
prop using v-model
(requires modelValue
prop to be define on the child component) and have the component emit an update:modelValue
event when the count changes. If don't want to use modelValue
as prop name and be more specific like count
, you can do v-model:count
, and then the child component will emit an update:count
event.
<scriptsetuplang="ts">
import{ ref }from'vue'
importCounterfrom'./components/Counter.vue'
</script>
<template>
<Counterv-model="counter">
<div>{{ count }}</div>
</template>
<scriptsetuplang="ts">
import{ computed }from'vue'
const props = defineProps<{ modelValue: number}>()
const emit = defineEmits<{ (e: "update:modelValue", value: number): void}>()
const modelValue = computed({ get: () => props.modelValue,set: (newValue) => { emit("update:modelValue", newValue)}})
</script>
<template>
<button@click="modelValue++">Increment</button>
</template>
The code above is a lot of boilerplate code for something that should be simple. With the defineModel
macro, we can simplify the code to the following:
<scriptsetuplang="ts">
const modelValue = defineModel<string>()
</script>
<template>
<button@click="modelValue++">Increment</button>
</template>
Now that's what I call a good refactor ✨. The defineModel
macro will automatically define the modelValue
prop and the update:modelValue
event for us. It will also infer the type of the prop based on the type we pass in.
Keep in mind that the defineModel
macro is just a macro, so it's not a new feature in Vue 3.3. It's just a new way of writing the same code. You can still use the old way of defining a model if you prefer. And to be able to use it you need to define it in the vite config file. You can also watch the below.
