L’introduzione della Composition API di Vue 3 rappresenta un’alternativa dichiarativa e modulare alla Options API, offrendo un approccio più flessibile e potente, particolarmente indicato per la creazione di codice modulare e riutilizzabile. Le Composition API permettono di raggruppare tutta la logica relativa a una singola funzionalità in un unico blocco, e l’organizzazione del codice per funzionalità rende molto semplice estrarre e condividere la logica tra componenti diversi.
VueUse sfrutta la potenza della Composition API per offrire una collezione di funzioni “composables“, agnostiche rispetto ai componenti, pensate per risolvere problemi comuni. A differenza delle librerie di componenti UI, il suo scopo è quello di fornire una raccolta di utility riutilizzabili che si integrano con il ciclo di vita dei componenti Vue.
Perché usare VueUse?
Uno dei principali vantaggi di VueUse è la sua capacità di astrarre la complessità di problemi comuni.
VueUse permette di astrarre la logica complessa e ripetitiva in funzioni riutilizzabili, le “composables“. Invece di scrivere manualmente la gestione di eventi, setTimeout, setInterval o di interagire con le API del browser, si importa una funzione già pronta. Questo riduce la quantità di codice boilerplate da scrivere, permettendo di concentrarsi sulla logica specifica della propria applicazione.
Ad esempio, monitorare le dimensioni della finestra del browser richiederebbe un addEventListener e un removeEventListener manuale. Con VueUse, è sufficiente usare useWindowSize, che gestisce la logica interna e la corretta pulizia delle risorse in modo automatico.
import { useWindowSize } from "@vueuse/core";
// useWindowSize restituisce due ref reattive: width e height
// Non c'è bisogno di gestire manualmente gli eventi 'resize' o di pulire i listener.
const { width, height } = useWindowSize();
Il codice equivalente per replicare la funzionalità di useWindowSize senza usare la libreria VueUse è il seguente:
import { ref, onMounted, onUnmounted } from "vue";
// 1. Creiamo due ref per memorizzare larghezza e altezza.
const width = ref(window.innerWidth);
const height = ref(window.innerHeight);
// 2. Creiamo una funzione per aggiornare i valori delle ref.
const updateWindowSize = () => {
width.value = window.innerWidth;
height.value = window.innerHeight;
};
// 3. Aggiungiamo un event listener quando il componente viene montato.
onMounted(() => {
window.addEventListener("resize", updateWindowSize);
});
// 4. Rimuoviamo l'event listener quando il componente viene smontato
// per prevenire memory leak.
onUnmounted(() => {
window.removeEventListener("resize", updateWindowSize);
});
Riutilizzabilità e Modularità
VueUse è un ottimo esempio del concetto di composables. Ogni funzione è un modulo isolato che può essere importato e utilizzato in qualsiasi componente Vue. Questo approccio promuove la scrittura di un codice più modulare, semplificando la condivisione della logica tra componenti e la manutenzione del codice a lungo termine, specialmente quando si lavora in team.
Ottimizzazione delle Performance
Le funzioni di VueUse sono ottimizzate per funzionare in modo efficiente con il sistema di reattività di Vue 3. La libreria è tree-shakable, il che significa che il tuo bundle finale includerà solo le funzioni effettivamente utilizzate, mantenendo il pacchetto il più leggero possibile.
Composables disponibili
La libreria VueUse è organizzata in diverse categorie logiche per facilitare la navigazione e l’uso delle sue funzioni. Le categorie principali sono:
- State: Funzioni per gestire lo stato reattivo in modi specifici. useLocalStorage e useSessionStorage sincronizzano lo stato di una ref con lo storage del browser. useRefHistory traccia la cronologia delle modifiche di una ref, permettendo funzionalità di “undo” e “redo”.
- Elements: Composables che interagiscono direttamente con il DOM, come useElementBounding, useElementVisibility, useResizeObserver, useEventListener.
- Sensors: API per interagire con i sensori del dispositivo o gli eventi del browser, ad esempio useMouse che traccia le coordinate del puntatore del mouse, onClickOutside che intercetta click all’esterno di un elemento specifico, useBattery che fornisce informazioni sullo stato della batteria del dispositivo.
- Browser: Una vasta raccolta di funzioni per interagire con le API del browser, come useClipboard, useFullscreen, usePreferredDark.
- Network: Funzioni dedicate alle interazioni di rete, come useFetch e useWebSocket, che gestiscono le richieste di fetching dati e le connessioni WebSocket con un’API reattiva.
- Watch: Questa categoria estende la funzionalità del watch di Vue con versioni migliorate o con funzionalità aggiuntive, come until, pausableWatch e debouncedWatch.
- Utilities: Funzioni generiche che semplificano compiti comuni, come createReusableTemplate, useTimeoutPoll e createGlobalState.
- Component: Funzioni che aiutano a gestire la logica dei componenti, come templateRef e useTemplateRefsList.
Oltre a queste categorie principali, esistono anche delle categorie dedicate a integrazioni con altre librerie popolari (come Vue Router, Firebase o RxJS) che si trovano spesso in pacchetti separati, ad esempio @vueuse/firebase.
Casi d'uso
La funzione until è un potente esempio di come VueUse possa semplificare la gestione degli stati asincroni. Permette di “attendere” che una variabile Ref o Reactive soddisfino una determinata condizione prima di procedere con l’esecuzione del codice. Questo è particolarmente utile per scenari di data fetching o per sincronizzare gli stati senza utilizzare watch a cascata.
Caso d’uso: un’applicazione deve gestire il seguente processo
- attendere che un token di autenticazione sia disponibile (ad esempio, dopo che l’utente ha effettuato il login)
- avviare il caricamento dei dati del profilo utente
- impostare lo stato dell’applicazione come “pronta” e mostrare la dashboard
Questo scenario si può risolvere con due watch separati che si attivano l’un l’altro, creando una catena di dipendenze.
Con until, l’intero processo può essere scritto in una singola funzione asincrona, migliorando la leggibilità e la chiarezza del flusso.
Caricamento in corso...
Dashboard Utente
Benvenuto, {{ userProfile.name }}!
La logica è lineare e facile da seguire, si possono concatenare più condizioni con await, trasformando un complesso watch a cascata in una sequenza chiara. Inoltre si può racchiudere l’intera funzione startAppFlow in un blocco try…catch per gestire tutti gli errori del flusso in un unico punto, anziché in ogni singolo watch.
La funzione useRefHistory permette di tracciare la cronologia di una variabile reattiva con una singola riga di codice.
Caso d’uso: l’utente può scrivere in un’area di testo, si vuole offrire la possibilità di annullare l’ultima modifica (undo) o di ripeterla (redo), come in un editor di testo.
Con questo approccio non bisogna gestire array di stati o scrivere logica complessa all’interno del componente Vue. useRefHistory(text) fa tutto quello che serve:
- undo() e redo() sono le funzioni che manipolano il valore di text
- canUndo e canRedo sono ref reattive che diventano true o false a seconda che ci siano azioni da annullare o ripetere
Conclusioni
VueUse si avvale della Composition API per fornire una collezione di funzioni generiche che offrono una soluzione semplice a molti casi d’uso comuni. Adottarlo significa non solo scrivere codice più pulito e manutenibile, ma anche aumentare la produttività della propria applicazione Vue.
La documentazione ufficiale di VueUse è il luogo migliore per esplorare l’intera gamma di funzioni disponibili.
