Javascript is required
ยท
3 min read

What's New in Vue 3.3

What's New in Vue 3.3 Image

Vue 3.3 "Rurouni Kenshin" is now available and "is focused on developer experience improvements".

In this article, I give an overview of the highlighted features in Vue 3.3. Read the changelog if you are interested in all changes of this new version.

Props Destructuring

Warning

This feature is experimental and requires explicit opt-in.

I think this is one of the coolest features of the new release. You can now destructure props without losing reactivity and also set default values:

1<script setup lang="ts">
2const { counter = 0, testId = 'counter' } = defineProps<{ counter?: number; testId?: string }>()
3</script>

In my opinion, this is a very clean and "natural" way to define your props. Previously you had to use toRefs in combination with withDefaults to achieve the same result:

1<script setup lang="ts">
2const { counter, testId } = toRefs(
3  withDefaults(defineProps<{ counter?: number; testId?: string }>(), { counter: 0, testId: 'counter' })
4)
5</script>

defineModel

Warning

This feature is experimental and requires explicit opt-in.

Vue 3.3 provides a very elegant way to support two-way binding with v-model. Before 3.3 you had to write a lot of boilerplate code to support it:

1<script setup>
2const props = defineProps(['modelValue'])
3const emit = defineEmits(['update:modelValue'])
4
5function onInput(event) {
6  emit('update:modelValue', event.target.value)
7}
8</script>
9
10<template>
11  <input :value="modelValue" @input="onInput" />
12</template>

With 3.3 we can achieve the same functionality with less code:

1<script setup>
2const modelValue = defineModel()
3</script>
4
5<template>
6  <input v-model="modelValue" />
7</template>

In this example, the defineModel macro automatically registers a prop modelValue and returns a ref that can be directly mutated. Additionally. it registers the update:modelValue event.

Improved TypeScript Type Support

In the past, only local types such as type literals and interfaces could be used in the type parameter position of the defineProps and defineEmits compiler macros.

The reason for this was that Vue needed to analyze the properties on the props interface to create runtime options. However, this limitation has been addressed in version 3.3. The Vue compiler can now handle imported types and a limited set of complex types:

1<script setup lang="ts">
2import type { Props } from './foo'
3
4// imported + intersection type