[Easy] Nuove Funzionalità di Vue3
1. Quali sono le nuove funzionalità di Vue 3?
Quali sono le principali nuove funzionalità di Vue 3?
Vue 3 ha introdotto molteplici importanti aggiornamenti:
Funzionalità principali
- Composition API
- Teleport
- Fragment (nodi root multipli)
- Suspense
- Binding
v-modelmultipli - Migliore supporto TypeScript
- Miglioramenti delle prestazioni (bundle più piccolo, rendering più veloce)
2. Teleport
Cos'è Teleport?
Teleport permette di renderizzare parte di un componente in un'altra posizione nell'albero DOM senza cambiare la struttura logica o la proprietà del componente.
Casi d'uso tipici
Modal, Tooltip, Notification, Popover, livelli overlay.
<template>
<div>
<button @click="showModal = true">Apri Modal</button>
<Teleport to="body">
<div v-if="showModal" class="modal">
<div class="modal-content">
<h2>Titolo del Modal</h2>
<p>Contenuto del Modal</p>
<button @click="showModal = false">Chiudi</button>
</div>
</div>
</Teleport>
</div>
</template>
<script setup>
import { ref } from 'vue';
const showModal = ref(false);
</script>
Perché Teleport è utile
- Risolve problemi di stacking context / z-index
- Evita il clipping causato dall'overflow degli antenati
- Mantiene la logica del componente collocata insieme mentre renderizza altrove
3. Fragment (Nodi Root Multipli)
Cos'è Fragment in Vue 3?
Vue 3 permette al template di un componente di avere nodi root multipli.
A differenza di React, Vue utilizza fragment impliciti (nessun tag <Fragment> aggiuntivo necessario).
Vue 2 vs Vue 3
Vue 2: root singolo obbligatorio.
<template>
<div>
<h1>Titolo</h1>
<p>Contenuto</p>
</div>
</template>
Vue 3: root multipli permessi.
<template>
<h1>Titolo</h1>
<p>Contenuto</p>
</template>
Perché Fragment è importante
- Meno elementi wrapper non necessari
- HTML semantico migliore
- Albero DOM meno profondo
- Stile e selettori più puliti
Ereditarietà degli attributi nei componenti multi-root
Con template multi-root, gli attributi del genitore (class, id, ecc.) non vengono applicati automaticamente a un root specifico.
Usare $attrs manualmente.
<!-- Genitore -->
<MyComponent class="custom-class" id="my-id" />
<!-- Figlio -->
<template>
<div v-bind="$attrs">Primo root</div>
<div>Secondo root</div>
</template>
Puoi controllare il comportamento con:
<script setup>
defineOptions({
inheritAttrs: false,
});
</script>
Fragment vs React Fragment
| Caratteristica | Vue 3 Fragment | React Fragment |
|---|---|---|
| Sintassi | Implicito (nessun tag necessario) | Esplicito (<> o <Fragment>) |
| Gestione key | Regole normali vnode/key nelle liste | Key supportata su <Fragment key=...> |
| Inoltro attr | Usare $attrs manualmente in multi-root | Nessun attr diretto sui fragment |
4. Suspense
Cos'è Suspense?
Suspense è un componente integrato per gli stati di caricamento delle dipendenze asincrone.
Renderizza una UI di fallback mentre il componente/setup asincrono si risolve.
Utilizzo base
<template>
<Suspense>
<template #default>
<AsyncComponent />
</template>
<template #fallback>
<div>Caricamento...</div>
</template>
</Suspense>
</template>
<script setup>
import { defineAsyncComponent } from 'vue';
const AsyncComponent = defineAsyncComponent(() =>
import('./AsyncComponent.vue')
);
</script>
Casi d'uso tipici
- Caricamento di componenti asincroni
- Requisiti di dati
setup()asincroni - UI skeleton a livello di route o sezione
5. v-model Multipli
Binding
v-modelmultipli
Vue 3 supporta binding v-model multipli su un singolo componente.
Ogni binding mappa su una prop + evento update:propName.
Vue 2 vs Vue 3
Vue 2: un solo pattern v-model per componente.
<CustomInput v-model="value" />
Vue 3: binding v-model multipli con nome.
<CustomForm
v-model:username="username"
v-model:email="email"
v-model:password="password"
/>
Esempio di implementazione del componente
<!-- CustomForm.vue -->
<template>
<div>
<input
:value="username"
@input="$emit('update:username', $event.target.value)"
/>
<input
:value="email"
@input="$emit('update:email', $event.target.value)"
/>
<input
:value="password"
@input="$emit('update:password', $event.target.value)"
/>
</div>
</template>
<script setup>
defineProps(['username', 'email', 'password']);
defineEmits(['update:username', 'update:email', 'update:password']);
</script>
6. Domande Comuni nei Colloqui
Domande comuni nei colloqui
Domanda 1: quando dovresti usare Teleport?
Clicca per vedere la risposta
Usare Teleport quando il rendering visuale deve sfuggire ai vincoli del DOM locale:
- Dialog modali per evitare problemi di stacking/overflow del genitore
- Tooltip/popover che non dovrebbero essere tagliati
- Notifiche globali renderizzate in un container root dedicato
Evitare Teleport per contenuto normale in-flow.
Domanda 2: vantaggi di Fragment
Clicca per vedere la risposta
Vantaggi:
- meno nodi wrapper
- migliore struttura semantica
- CSS più semplice in molti layout
- meno profondità DOM e sovraccarico
Domanda 3: ereditarietà degli attributi multi-root
Clicca per vedere la risposta
Per componenti multi-root, gli attrs non vengono auto-ereditati su un singolo root.
Gestirli esplicitamente con $attrs e opzionalmente inheritAttrs: false.
<template>
<div v-bind="$attrs">Root A</div>
<div>Root B</div>
</template>
Domanda 4: Fragment in Vue vs React
Clicca per vedere la risposta
Vue utilizza il comportamento fragment implicito nei template.
React richiede una sintassi fragment esplicita (<>...</> o <Fragment>).
Domanda 5: esempio di implementazione Suspense
Clicca per vedere la risposta
<template>
<Suspense>
<template #default>
<AsyncUserProfile :userId="userId" />
</template>
<template #fallback>
<div class="loading">
<Spinner />
<p>Caricamento profilo utente...</p>
</div>
</template>
</Suspense>
</template>
<script setup>
import { ref, defineAsyncComponent } from 'vue';
import Spinner from './Spinner.vue';
const userId = ref(1);
const AsyncUserProfile = defineAsyncComponent(() =>
import('./UserProfile.vue')
);
</script>
7. Best Practices (Buone Pratiche)
Buone pratiche
Raccomandato
<!-- 1) Usare Teleport per overlay -->
<Teleport to="body">
<Modal v-if="showModal" />
</Teleport>
<!-- 2) Mantenere template multi-root semantici dove appropriato -->
<template>
<header>...</header>
<main>...</main>
<footer>...</footer>
</template>
<!-- 3) Avvolgere le parti asincrone con Suspense -->
<Suspense>
<AsyncComponent />
<template #fallback>
<LoadingSpinner />
</template>
</Suspense>
<!-- 4) Usare nomi espliciti per v-model multipli -->
<CustomForm v-model:username="username" v-model:email="email" />
Da evitare
<!-- 1) Non abusare di Teleport per contenuto regolare -->
<Teleport to="body">
<div>Contenuto normale</div>
</Teleport>
<!-- 2) Non usare multi-root solo per stile; mantenere raggruppamento logico -->
<template>
<h1>Titolo</h1>
<p>Contenuto</p>
</template>
<!-- 3) Non ignorare la gestione di errori/caricamento asincrono -->
<Suspense>
<AsyncComponent />
</Suspense>
8. Riepilogo per i Colloqui
Riepilogo per i colloqui
Promemoria rapido
Funzionalità chiave di Vue 3:
- Composition API
- Teleport
- Fragment
- Suspense
v-modelmultipli
Risposta esempio
D: Quali sono le principali funzionalità di Vue 3?
Composition API per una migliore organizzazione e riutilizzo della logica, Teleport per il rendering di overlay fuori dai container DOM locali, Fragment per nodi root multipli, Suspense per stati di caricamento asincrono, binding
v-modelmultipli, e miglioramenti più forti di TypeScript/prestazioni.
D: Qual è un caso d'uso pratico di Teleport?
Rendering di modal/overlay nel
bodyper evitare problemi di clipping e stacking, mantenendo la logica del modal all'interno dell'albero dei componenti originale.