In questa breve lezione, illustriamo quali modifiche sono state apportate in Vue 3 per quanto riguarda le transizioni.
Le prima novità significativa riguarda i nomi delle classi CSS che vengono automaticamente aggiunti da Vue agli elementi su cui vogliamo applicare una transizione in ingresso e uscita.
In Vue 2, durante il processo di transizione in ingresso, <transition>
applica automaticamente 3 diverse classi al momento opportuno.
Si tratta di:
- v-enter
- v-enter-to
- v-enter-active
Per chiarire quale sia la differenza fra lo stato iniziale e finale della transizione, la classe v-enter
è stata rinominata v-enter-from
.
Le classi usate in Vue 3 sono quindi le seguenti:
- v-enter-from
- v-enter-to
- v-enter-active
Attraverso la stessa illustrazione già vista nella precedente lezione, possiamo evidenziare la differenza.
In modo analogo è stata anche rinominata la classe che viene automaticamente applicata all’inizio di una transizione in uscita.
In Vue 3 vengono dunque applicate le seguenti classi durante la transizione di uscita.
- v-leave-from
- v-leave-to
- v-leave-active
Ricapitolando, in Vue 3 l’unica differenza per le transizioni consiste nel nome delle due classi usate all’inizio delle transizioni di ingresso e uscita di un elemento dal DOM.
Come implementare una semplice transizione in Vue 3 con la Composition API
Vediamo allora un banale esempio di transizione in dissolvenza in cui useremo anche la Composition API. Cliccando su un pulsante cambieremo lo stato corrente di un paragrafo.
Per semplicità creiamo una nuova cartella in cui aggiungiamo i due file index.html e app.js.
Nel file index.html inseriamo un elemento <script>
per scaricare la versione di Vue 3 da UNPKG ed un altro per importare il file app.js
.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Transizioni in Vue 3</title>
<style>
.fade-enter-active,
.fade-leave-active {
transition: opacity 500ms ease-out;
}
.fade-enter-from,
.fade-leave-to {
opacity: 0;
}
.fade-leave-from,
.fade-enter-to {
opacity: 1;
}
</style>
</head>
<body>
<div id="app">
<button @click="toggle">{{ buttonLabel }}</button>
<transition name="fade">
<p v-if="visible">
Lorem ipsum dolor sit amet consectetur adipisicing elit. Dignissimos,
dicta corrupti fugiat modi ipsum maxime commodi voluptatibus ratione
accusantium minus obcaecati voluptatem beatae animi quam, veniam quibusdam
perferendis optio eveniet?
</p>
</transition>
</div>
<!-- preleva Vue 3 dalla CDN di unpkg. Etichetta @next necessaria -->
<!-- al momento della stesura della guida -->
<script src="https://unpkg.com/vue@next"></script>
<script src="app.js"></script>
</body>
</html>
Il template della nostra applicazione è racchiuso fra i tag dell’elemento <div class="app">
. È presente un pulsante che, se premuto, esegue la funzione toggle()
la quale inverte il valore della variabile booleana visible
. Quando visible
è pari a false
il paragrafo viene rimosso dal DOM.
Per applicare una semplice transizione, abbiamo racchiuso il paragrafo tra i tag del componente <transition>. Tramite l’attributo name
personalizziamo il nome delle classi da applicare in fase di ingresso e rimozione del paragrafo dal DOM.
Vue si occuperà di applicare opportunamente le sei classi con prefisso fade- che, in base a quanto stabilito dalle nostre regole CSS, permetteranno di applicare un effetto di dissolvenza al paragrafo.
Ricordiamo che avremmo anche potuto rimuovere le regole per le classi .fade-leave-from e .fade-enter-to visto che il valore predefinito dell’opacità di un elemento è 1.
Passiamo al file app.js
ed analizziamo il codice in esso presente.
Per semplificare il codice, salviamo un riferimento alle funzioni createApp()
e ref()
dell’oggetto Vue nelle omonime costanti. Avendo scaricato il codice sorgente del framework da una CDN, l’oggetto Vue è infatti disponibile globalmente.
const { createApp, ref } = window.Vue;
const app = createApp({
setup() {
const labels = ['Mostra paragrafo', 'Nascondi paragrafo'];
const visible = ref(true);
const buttonLabel = ref(labels[1]);
function toggle() {
visible.value = !visible.value;
buttonLabel.value = labels[Number(visible.value)];
}
return {
visible,
buttonLabel,
toggle
}
}
});
app.mount("#app");
Creiamo poi l’istanza base dell’applicazione passando alla funzione createApp
un oggetto di configurazione che ha come unico metodo setup()
. In questo modo possiamo definire il comportamento dell’applicazione tramite Composition API invece dell’Option API.
Nel metodo setup()
creiamo un array labels
che contiene le due possibili etichette del pulsante presente nel template.
Tramite la funzione ref()
chiediamo a Vue di osservare i valori di visible
e buttonLabel
aggiungendoli al sistema di reattività del framework. In questo modo Vue sarà in grado di aggiornare automaticamente il template dell’applicazione quando uno dei due subisce una modifica.
L’aspetto negativo della funzione ref()
è rappresentato dal fatto che viene restituito un oggetto wrapper il quale mantiene il valore corrente all’interno di una proprietà value
. Inizialmente visible.value
è pari a true
e buttonLabel.value
è uguale a labels[1]
, ovvero ‘Nascondi paragrafo’.
Definiamo inoltre una funzione toggle()
che permette di invertire il valore di visible.value
(true/false) e, sfruttando la funzione globale Number(), convertiamo visible.value
in un valore numerico, 0 (se visible.value
è pari a false) o 1. Avremmo potuto effettuare la conversione anteponendo semplicemente il segno ‘+’ a visible.value
. Avremmo ottenuto lo stesso risultato, ma l’uso della funzione Number()
rende il codice più leggibile.
Infine, per rendere la funzione toggle()
e le proprietà reattive visible
e buttonLabel
disponibili nel template, restituiamo un oggetto. Dato che il nome delle chiavi coincide con quello dei valori, sfruttiamo la sintassi introdotta in ES2015 ed omettiamo quest’ultimo.
Ricordiamo che la funzione ref()
restituisce un oggetto che mantiene il valore passato come argomento all’interno di una proprietà .value
. Al contrario di quanto accade nel codice scritto in JS, nel template non è necessario accedere a tale proprietà per prelevare il valore. Infatti se controlliamo nuovamente il codice HTML presente nel file index.html
, Vue ci permette di accedere direttamente al valori di buttonLabel
e visible
.
Transition Group in Vue 3
Nell’esempio appena visto, abbiamo utilizzato un’altra interessante novità di Vue 3. Se torniamo al template dell’applicazione, notiamo infatti che abbiamo più di un componente radice e non abbiamo dovuto racchiudere <button>
e <transition>
in un altro elemento come in Vue 2.
Proprio per questa nuova funzionalità, che prende il nome di Fragments, in Vue 3 è stata apportata una modifica al comportamento di <transition-group>
che non utilizza più un elemento contenitore per racchiudere i nodi del DOM compresi fra i suoi tag di apertura e chiusura.
Per questo motivo in Vue 3 dovremo indicare esplicitamente quale deve essere l’elemento contenitore tramite la prop tag
.
<transition-group tag="ul">
<!-- nodi su cui applicare la transizione -->
</transition-group>