Vue 3.5: Aggiornamenti e Miglioramenti Performance
Scopri Vue.js 3.5 Tengen: Reactive Props Destructure, ottimizzazioni SSR, nuovo useTemplateRef, miglioramenti Teleport e performance eccezionali.

Vue 3.5 "Tengen" è stato rilasciato il 3 settembre 2024 con focus su performance, developer experience e nuove API reattive. Questa release introduce Reactive Props Destructure, ottimizzazioni significative per SSR e diversi miglioramenti all'API Composition.
🎯 Novità Principali
Reactive Props Destructure
Finalmente è possibile destrutturare props mantenendo la reattività:
<script setup>
// ❌ Vue 3.4 - perde reattività
const { msg, count } = defineProps(['msg', 'count']);
watch(() => msg, (newMsg) => {
// Non si triggera mai! msg non è reattivo
console.log(newMsg);
});
// ✅ Vue 3.5 - mantiene reattività!
const { msg, count } = defineProps(['msg', 'count']);
watch(() => msg, (newMsg) => {
// Funziona perfettamente!
console.log(newMsg);
});
// Con TypeScript
interface Props {
msg: string;
count: number;
disabled?: boolean;
}
const { msg, count, disabled = false } = defineProps<Props>();
// Default values con destructuring
const { title = 'Default Title', items = [] } = defineProps<{
title?: string;
items?: string[];
}>();
</script>
<template>
<div>
<h1>{{ msg }}</h1>
<p>Count: {{ count }}</p>
<button :disabled="disabled">Click</button>
</div>
</template>
Vantaggi:
- Codice più pulito e leggibile
- Default values nel destructuring
- Reattività completa mantenuta
- Migliore DX con meno boilerplate
useTemplateRef() API
Nuovo modo per accedere ai template refs:
<script setup>
import { useTemplateRef, onMounted } from "vue";
// ❌ Vue 3.4 - ref manual
import { ref, onMounted } from "vue";
const inputRef = ref(null);
onMounted(() => {
inputRef.value?.focus();
});
// ✅ Vue 3.5 - useTemplateRef
const inputRef = useTemplateRef("myInput");
onMounted(() => {
inputRef.value?.focus();
});
// Con TypeScript
const inputRef = useTemplateRef < HTMLInputElement > "myInput";
onMounted(() => {
inputRef.value?.select(); // Type-safe!
});
// Multiple refs
const buttonRefs = useTemplateRef < HTMLButtonElement > "buttons";
</script>
<template>
<input ref="myInput" type="text" />
<!-- Con v-for -->
<button v-for="i in 5" :key="i" :ref="'buttons'">Button {{ i }}</button>
</template>
Ottimizzazioni SSR Drastiche
Vue 3.5 introduce miglioramenti massicci per SSR:
Performance Improvements:
- 2x più veloce hydration
- -56% memoria utilizzata durante SSR
- Lazy hydration per componenti pesanti
<!-- app.vue -->
<script setup>
import { defineAsyncComponent } from "vue";
// Lazy hydration per componenti pesanti
const HeavyChart = defineAsyncComponent({
loader: () => import("./HeavyChart.vue"),
hydrate: "idle", // Hydrate quando idle
});
const VideoPlayer = defineAsyncComponent({
loader: () => import("./VideoPlayer.vue"),
hydrate: "visible", // Hydrate quando visibile
});
const InteractiveMap = defineAsyncComponent({
loader: () => import("./InteractiveMap.vue"),
hydrate: "interaction", // Hydrate al primo click
});
</script>
<template>
<div>
<h1>Dashboard</h1>
<!-- Lazy hydration strategies -->
<HeavyChart :data="chartData" />
<VideoPlayer src="/video.mp4" />
<InteractiveMap :markers="locations" />
</div>
</template>
Teleport con defer
Teleport ora supporta rendering differito:
<script setup>
import { ref } from "vue";
const showModal = ref(false);
</script>
<template>
<div>
<button @click="showModal = true">Open Modal</button>
<!-- defer: aspetta che #modal-target sia pronto -->
<Teleport to="#modal-target" defer>
<div v-if="showModal" class="modal">
<h2>Modal Content</h2>
<button @click="showModal = false">Close</button>
</div>
</Teleport>
</div>
<!-- Target può essere definito dopo -->
<div id="modal-target"></div>
</template>
Benefici:
- Nessun errore se target non esiste ancora
- Ordine dichiarazione più flessibile
- SSR-friendly
⚡ Miglioramenti Performance
Reactivity System Ottimizzato
// Vue 3.5 - reactivity engine migliorato
import { ref, computed, watch } from "vue";
// Performance migliorate per computed chains
const base = ref(10);
const doubled = computed(() => base.value * 2);
const quadrupled = computed(() => doubled.value * 2);
const octupled = computed(() => quadrupled.value * 2);
// Vue 3.5: 20-30% più veloce per computed complessi
Memory Usage Ridotto
<script setup>
// Vue 3.5 usa meno memoria per:
// - Large lists
// - Deep reactive objects
// - Computed chains
// - Watchers
const items = ref(
Array.from({ length: 10000 }, (_, i) => ({
id: i,
name: `Item ${i}`,
data: {
/* nested data */
},
}))
);
// -30% memory usage vs Vue 3.4
</script>
Custom Elements Migliorati
// defineCustomElement ottimizzato
import { defineCustomElement } from "vue";
import MyComponent from "./MyComponent.vue";
const MyWebComponent = defineCustomElement(MyComponent);
customElements.define("my-component", MyWebComponent);
// Features Vue 3.5:
// - Shadow DOM ottimizzato
// - Props binding più veloce
// - Event handling migliorato
🔧 Nuove API e Miglioramenti
onWatcherCleanup()
Cleanup più pulito per watchers:
<script setup>
import { watch, onWatcherCleanup } from "vue";
const searchQuery = ref("");
watch(searchQuery, async (query) => {
const controller = new AbortController();
// Cleanup automatico quando watcher ri-esegue
onWatcherCleanup(() => {
controller.abort();
});
try {
const response = await fetch(`/api/search?q=${query}`, {
signal: controller.signal,
});
const data = await response.json();
// Process data...
} catch (err) {
if (err.name === "AbortError") {
console.log("Request aborted");
}
}
});
</script>
useId() per SSR
Genera ID unici SSR-safe:
<script setup>
import { useId } from "vue";
const id = useId(); // Consistente tra server e client
// Utile per accessibilità
const labelId = `label-${id}`;
const inputId = `input-${id}`;
</script>
<template>
<div>
<label :id="labelId" :for="inputId"> Username </label>
<input :id="inputId" :aria-labelledby="labelId" />
</div>
</template>
app.config.errorHandler Migliorato
// main.js
import { createApp } from "vue";
import App from "./App.vue";
const app = createApp(App);
app.config.errorHandler = (err, instance, info) => {
// Vue 3.5: info più dettagliato
console.error("Error:", err);
console.log("Component:", instance?.$options.name);
console.log("Error Info:", info); // lifecycle hook, event handler, etc.
// Invia a error tracking
if (import.meta.env.PROD) {
trackError(err, { component: instance, info });
}
};
app.mount("#app");
🎨 Composition API Enhancements
defineModel() Miglioramenti
<!-- ParentComponent.vue -->
<script setup>
import { ref } from "vue";
import ChildComponent from "./ChildComponent.vue";
const searchQuery = ref("");
const filters = ref({ category: "all", sort: "name" });
</script>
<template>
<ChildComponent v-model="searchQuery" v-model:filters="filters" />
</template>
<!-- ChildComponent.vue -->
<script setup>
// Vue 3.5: defineModel più potente
const query = defineModel({ type: String, required: true });
const filters = defineModel("filters", {
type: Object,
default: () => ({ category: "all", sort: "name" }),
});
// Trasformazioni
const upperQuery = defineModel({
get: (value) => value.toUpperCase(),
set: (value) => value.toLowerCase(),
});
</script>
<template>
<div>
<input v-model="query" placeholder="Search..." />
<select v-model="filters.category">
<option value="all">All</option>
<option value="tech">Tech</option>
</select>
</div>
</template>
defineOptions() Esteso
<script setup>
// Vue 3.5: più opzioni supportate
defineOptions({
name: "MyComponent",
inheritAttrs: false,
customOptions: {
// Custom options per plugin
},
});
const props = defineProps({
msg: String,
});
</script>
🔄 Come Aggiornare a Vue 3.5
Installazione
# npm
npm install vue@latest
# yarn
yarn add vue@latest
# pnpm
pnpm add vue@latest
# Verifica versione
npm list vue
Per Progetti Vite
# Aggiorna anche Vite plugin
npm install -D @vitejs/plugin-vue@latest
# vite.config.js
import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';
export default defineConfig({
plugins: [
vue({
// Abilita nuove features
script: {
defineModel: true,
propsDestructure: true
}
})
]
});
TypeScript Setup
// tsconfig.json
{
"compilerOptions": {
"target": "ES2020",
"module": "ESNext",
"lib": ["ES2020", "DOM", "DOM.Iterable"],
"jsx": "preserve",
"moduleResolution": "bundler",
"types": ["vite/client"]
}
}
⚠️ Breaking Changes
1. Reactivity Transform Rimosso
<!-- ❌ Non più supportato -->
<script setup>
let count = $ref(0);
const doubled = $computed(() => count * 2);
</script>
<!-- ✅ Usa Composition API standard -->
<script setup>
import { ref, computed } from "vue";
const count = ref(0);
const doubled = computed(() => count.value * 2);
</script>
2. Async Component Type
// ❌ Vue 3.4
const AsyncComp = defineAsyncComponent(() => import("./Component.vue"));
// ✅ Vue 3.5 - type più specifico
import { defineAsyncComponent, type Component } from "vue";
const AsyncComp: Component = defineAsyncComponent(
() => import("./Component.vue")
);
3. Custom Directives
Alcune signature interne cambiate - aggiorna custom directives se necessario.
🎓 Best Practices
1. Usa Props Destructure
<script setup>
// ✅ Pulito e reattivo
const { title, items = [], loading = false } = defineProps<{
title: string;
items?: Item[];
loading?: boolean;
}>();
</script>
2. useTemplateRef per Refs
<script setup>
// ✅ Più esplicito e type-safe
const inputRef = useTemplateRef < HTMLInputElement > "input";
</script>
3. Lazy Hydration per SSR
<script setup>
// ✅ Migliori performance SSR
const HeavyComponent = defineAsyncComponent({
loader: () => import("./Heavy.vue"),
hydrate: "visible",
});
</script>
4. onWatcherCleanup per Async
<script setup>
// ✅ Cleanup automatico
watch(query, async (q) => {
const controller = new AbortController();
onWatcherCleanup(() => controller.abort());
await fetch(url, { signal: controller.signal });
});
</script>
📊 Performance Benchmark
| Operazione | Vue 3.4 | Vue 3.5 | Miglioramento |
|---|---|---|---|
| SSR render | 100ms | 50ms | 2x |
| Hydration | 80ms | 40ms | 2x |
| Large list | 150ms | 120ms | 20% |
| Deep reactivity | 200MB | 140MB | -30% |
🔗 Risorse Utili
💡 Conclusioni
Vue 3.5 "Tengen" è un aggiornamento eccellente:
✅ Reactive Props Destructure per codice più pulito ✅ Performance SSR 2x migliorate ✅ useTemplateRef per refs più esplicite ✅ Memory optimization significativa ✅ Developer Experience migliorata
Quando aggiornare:
- ✅ Compatibile con Vue 3.4 (no breaking changes maggiori)
- ✅ Aggiorna subito per beneficiare delle performance
- ✅ SSR projects beneficiano enormemente
Vue continua a evolversi mantenendo semplicità e performance eccellenti!