Vue.js has officially released the stable version of Vue.js 3.5, and the updates for version 3.5 can already be found on Vue’s official documentation. This version does not include any major changes but rather includes internal improvements and practical new features. Below, let’s explore a few of the more interesting alterations.
Reactive Props Destructure
Prior to Vue 3.5, to achieve responsive destructuring of props, you would use the toRef() API to create reactive references for individual properties within the props object. Here’s an example of how you could do this:
import { toRef } from 'vue'
const props = defineProps<{
count: number
}>()
// Create a reactive reference for the 'count' prop
const count = toRef(props, 'count')
// Define a method to log the value of the reactive reference
const log = () => {
console.log(count.value)
}
Reactive Props Destructuring Method in Vue 3.5
// Vue 3.5 allows for direct reactive destructuring of props
const { count } = defineProps<{
count: number
}>();
// Testing the reactivity of 'count'. The button click in the child component will output the destructured 'count' value.
const log = () => {
console.log(count);
};
In Vue 3.5, accessing destructured variables such as count is automatically compiled by the compiler into props.count, allowing for tracking of these accesses. This enables the variable count to be reactive, meaning it will update automatically if the corresponding prop changes.
Default Values for Props
Before Vue 3.5:
// Using TypeScript generics for default values (compile-time)
const props = withDefaults(
defineProps<{
count: number
}>(),
{
count: 0
}
)
// Using JavaScript for default values (runtime)
const props = defineProps({
count: {
type: Number,
default: 2
}
})
In Vue 3.5:
// TypeScript syntax
const { count = 1 } = defineProps<{
count: number
}>()
// JavaScript syntax
const { count = 2 } = defineProps({
count: String // Note: This should be Number if you want a numeric default, but the example kept it as String for consistency with the provided code.
})
You can now assign default values directly using object destructuring syntax, similar to JavaScript, significantly reducing cognitive load for developers! This is a welcome improvement!
useTemplateRef()
useTemplateRef()
for Accessing Template References
<template>
<div class="list" ref="listEl">
<div ref="itemEl" class="item" v-for="item in list" :key="item">
{{ item }}
</div>
</div>
</template>
<script setup lang="ts">
import { useTemplateRef, onMounted } from 'vue'
const list = [1,2,3]
const listRef = useTemplateRef('listEl')
const itemRef = useTemplateRef('itemEl')
onMounted(() => {
console.log(listRef.value) // div.list
console.log(itemRef.value) // An array of Proxy objects representing the div.items
})
</script>
When multiple elements with the same ref
are bound in the template, useTemplateRef()
returns an array, as shown above with the div
elements rendered via v-for
and bound to ref="itemEl"
.
Optimizations to the Component
A known limitation of the built-in <Teleport>
component is that its target element must exist when the <Teleport>
component is mounted. In Vue 3.5, the <Teleport>
component introduces a defer
prop that mounts it after the current render cycle, as demonstrated below:
<Teleport defer to="#cont">
<div v-if="open">
<span>Mounted to the div with id "cont"</span>
<button @click="open = false">Close</button>
</div>
</Teleport>
<!-- Container for Teleported content -->
<div id="cont"></div>
<button @click="open = true">Open</button>
Since <div id="cont"></div>
is rendered after <Teleport>
, the defer prop is needed to delay the mounting of the <Teleport>
component. If <div id="cont"></div>
is rendered before <Teleport>
, the defer
prop is not required.
useId() for Generating Unique Application IDs
useId()
can be used to generate unique IDs for each application, ensuring consistency during server-side and client-side rendering. It can be used to generate IDs for form elements and accessibility attributes and works seamlessly in SSR applications without causing ID conflicts:
<script setup>
import { useId } from 'vue'
const id = useId()
</script>
<template>
<form>
<label :for="id">Name:</label>
<input :id="id" type="text" />
</form>
</template>
This can be simply used as an API for generating unique IDs.
Apart from what has been mentioned above, Vue 3.5 has also undergone a reconstruction of its reactive system, resulting in performance enhancements. It is reported that in certain scenarios, this can lead to a 10-fold improvement in performance.