Composition API vs Options API in Vue 3 per grandi librerie di componenti
Composition API vs Options API in Vue 3: come ciascuno influisce su riuso, testing e onboarding per grandi librerie di componenti admin e team di contributori.

Perché questa scelta conta nelle grandi librerie di componenti admin
Una grande libreria di componenti in un'app admin non è un sito di marketing con pochi pulsanti. Sono dozzine (o centinaia) di blocchi riutilizzabili che si ripetono nelle schermate: tabelle dati con ordinamento e azioni in blocco, pannelli di filtro, form con regole di validazione, drawer e modal, flow di conferma e piccole utility come date picker e guardie di permessi.
Perché questi pattern ricorrono ovunque, i team spesso copiano e modificano il codice per rispettare le scadenze. Una tabella ha una barra di filtro personalizzata, un'altra ne ha una leggermente diversa, e presto hai cinque versioni “quasi uguali”. È a questo punto che la scelta Composition API vs Options API smette di essere una preferenza personale e comincia a influire sulla salute dell'intera libreria.
Quel che di solito si rompe prima è la coerenza. L'interfaccia funziona ancora, ma il comportamento deriva: una modal si chiude con Escape in un punto ma non in un altro; lo stesso campo del form valida al blur in una pagina e alla submit in un'altra. Dopo, la velocità rallenta perché ogni modifica richiede di cercare tra quasi-duplicati. Infine, cala la fiducia: le persone evitano i refactor perché non riescono a prevedere cosa verrà influenzato.
Tre decisioni pratiche contano più di altre in una libreria condivisa:
- Riuso del codice: come impacchetti la logica condivisa senza dipendenze aggrovigliate.
- Testing: quanto è semplice verificare il comportamento senza test fragili e pesanti sull'UI.
- Onboarding: quanto rapidamente un nuovo contributore può leggere un componente e fare una modifica sicura.
Un esempio semplice: il tuo admin ha 20 pagine lista e il prodotto chiede una nuova funzionalità “Filtri salvati”. Se la tabella, i filtri e la logica di sincronizzazione con l'URL sono sparsi e inconsitenti, o la consegni lentamente o la consegni con bug. Lo stile di API scelto determina se quella logica vive in un posto riutilizzabile, quanto chiaramente è collegata a ogni schermata e quanto facilmente qualcuno di nuovo può estenderla.
Se stai costruendo app admin Vue 3 (inclusi team che usano Vue 3 dentro piattaforme come AppMaster per lo strato UI web), prendere questa decisione presto può risparmiare mesi di manutenzione in seguito.
Come Options e Composition differiscono nel codice quotidiano
Il modo più veloce per percepire la differenza è aprire un componente admin grande e chiederti: “Dove cambio il comportamento per questa feature?”. In una libreria di componenti quella domanda si presenta ogni giorno.
Con l'Options API, il codice è raggruppato per tipo: data per lo stato, methods per le azioni, computed per i valori derivati e watch per gli effetti collaterali. Questa struttura è facile da scorrere quando un componente è piccolo. In una tabella o in un form complesso, la logica di una singola feature (come le azioni in blocco o la validazione di un campo) spesso finisce distribuita in più blocchi. Si può mantenere ordinato, ma serve disciplina e naming consistente per evitare il flusso di lavoro “salta in giro nel file”.
Con la Composition API, il codice è spesso raggruppato per feature. Definisci stato correlato, valori derivati, effetti collaterali e helper vicini tra loro, e puoi estrarre la logica ripetuta in composables. In una libreria in stile admin questo di solito rispecchia il modo di pensare delle persone: “tutto ciò che riguarda il filtro è qui”, “tutto sulla selezione delle righe è qui”. Può anche ridurre la duplicazione tra componenti simili, per esempio riutilizzando un usePagination in più tabelle.
Una differenza pratica giornaliera è come emergono le dipendenze.
- L'Options API può sembrare più implicita: un metodo può dipendere da
this.user,this.filtersethis.loading, e lo scopri solo leggendo dentro il metodo. - La Composition API tende a essere più esplicita: quando una funzione chiude su
filterseloading, vedi quelle variabili definite nelle vicinanze e puoi passarle a funzioni helper quando necessario.
Il compromesso è che la Composition API può diventare rumorosa se tutto viene gettato in un unico setup() senza struttura.
Una regola pratica:
- Scegli Options API quando i componenti sono principalmente presentazionali e hanno logica leggera.
- Scegli Composition API quando i componenti hanno più feature con regole condivise nella libreria.
- Se scegli Composition API, concorda una semplice organizzazione che raggruppi il codice per feature (non “tutti i ref per primi”).
- Se scegli Options API, fai rispettare naming e tieni la logica correlata insieme con brevi commenti e nomi di metodi coerenti.
Entrambi possono funzionare. La chiave è scegliere lo stile di organizzazione che rende la prossima modifica ovvia, non una trovata ingegnosa.
Riuso del codice: cosa scala in modo pulito e cosa diventa disordinato
Negli admin, il riuso non è un optional. Ripeti gli stessi comportamenti in dozzine di schermate e piccole incoerenze diventano bug e ticket di supporto.
La maggior parte dei bisogni di riuso rientra in alcuni insiemi ricorrenti: ordinamento/filtri/paginazione che rispecchiano il backend, validazione dei form e mapping degli errori, controlli di permesso e gating UI, sincronizzazione query (parametri URL, viste salvate, filtri di default) e azioni in blocco con regole di selezione nella tabella.
Riuso con Options API: potente, ma facile nascondere la complessità
Con l'Options API il riuso spesso inizia con mixin, extends o plugin.
I mixin sono rapidi, ma scalano male perché nascondono da dove proviene un metodo o un valore computed. Due mixin possono silenziosamente collidere sullo stesso nome di metodo, e ora stai debugando un comportamento che non è visibile nel file del componente.
extends può sembrare più pulito dei mixin, ma crea comunque puzzle di ereditarietà dove devi leggere più file per capire cosa fa davvero un componente. I plugin funzionano bene per preoccupazioni a livello di app (directive globali, servizi condivisi), ma non sono il posto migliore per regole di business che variano per schermata.
Il momento disordinato arriva quando il riuso diventa implicito. I nuovi contributori non riescono a rispondere a “da dove viene questo dato?” senza cercare in tutto il codebase.
Riuso con Composition API: composables che restano espliciti
Il riuso con Composition API si costruisce solitamente attorno ai composables: funzioni piccole che restituiscono refs, valori computed e handler. Il grande vantaggio è che il riuso diventa visibile vicino alla parte superiore del componente, e puoi passare parametri invece di fare affidamento su un contesto componente nascosto.
Per esempio, un usePagination può accettare default ed emettere cambiamenti in una forma coerente, mentre usePermissions può accettare il ruolo corrente e il nome della feature. A quel punto la scelta diventa meno sintattica e più su quanto la tua libreria preferisca wiring esplicito rispetto a ereditarietà implicita.
Per mantenere il riuso prevedibile, tratta ogni unità riutilizzabile come una piccola API: dagli un nome chiaro, definisci input e output e mantieni una singola responsabilità. Se un composable inizia a gestire paginazione, caching, permessi e notifiche, dividilo. È molto più semplice sostituire un pezzo in seguito senza rompere tutto il resto.
Costruire form e tabelle riutilizzabili senza dolore
Nei progetti admin, form e tabelle sono il punto in cui una libreria di componenti o ripaga o diventa un labirinto. Entrambi gli API possono funzionare. La differenza è come impacchetti comportamenti condivisi come dirty state, mapping degli errori e flow di submit senza far sembrare ogni componente “speciale”.
Per la logica condivisa dei form, l'Options API spesso ti spinge verso mixin o helper condivisi. I mixin possono sembrare comodi all'inizio, ma dopo diventa difficile rispondere a domande basilari: “Da dove viene questo errore di campo?” o “Perché il pulsante submit è disabilitato?”.
La Composition API rende questo tipo di riuso più visibile perché puoi spostare la logica in composables (per esempio useDirtyState, useFormErrors, useSubmitFlow) e vedere esattamente cosa un componente form importa. In una grande libreria quella chiarezza conta spesso più che risparmiare qualche riga.
Un modo pratico per mantenere stabili le API dei componenti è trattare la surface pubblica come un contratto: props, emits e slot dovrebbero cambiare raramente, anche se riscrivi l'interno. Quel contratto sembra lo stesso in entrambi gli stili, ma la Composition API spesso rende i refactor più sicuri perché puoi sostituire un composable alla volta senza toccare l'API del template.
Pattern che di solito rimangono sani con la crescita della libreria:
- Costruisci componenti base che fanno una cosa bene (BaseInput, BaseSelect, BaseTable), poi comporli in componenti feature.
- Preferisci slot per la flessibilità di layout (area azioni, stati vuoti, rendering delle celle) invece di aggiungere props per ogni caso limite.
- Normalizza eventi presto (per esempio
update:modelValue,submit,rowClick) così le app non dipendono da dettagli interni. - Tieni validazione e formattazione vicino agli input, ma regole di business fuori (in composables o nei container genitori).
L'over-astrazione è la trappola comune. Un “super form” che gestisce ogni tipo di campo, ogni regola di validazione e ogni opzione di layout spesso diventa più difficile da usare del semplice Vue. Una buona regola è: se un componente base ha bisogno di più di una manciata di props per coprire i bisogni di tutti i team, probabilmente sono due componenti.
A volte la duplicazione è la scelta giusta. Se solo una schermata ha bisogno di un'intestazione tabella strana con raggruppamento multiriga, copia un piccolo pezzo e mantienilo locale. Le astuzie hanno una lunga coda di manutenzione, specialmente quando arrivano nuovi contributori che cercano di capire la differenza tra componenti “normali” e un framework dentro il framework.
Se stai decidendo tra Composition e Options per una grande libreria di form e tabelle, ottimizza prima per la leggibilità del flusso dei dati. Il riuso è ottimo, ma non quando nasconde il percorso dall'azione utente all'evento emesso.
Impatto sul testing: cosa diventa più facile da verificare
In una libreria di componenti i test cadono solitamente in tre categorie: logica pura (formattazione, validazione, filtraggio), rendering (cosa viene mostrato per uno stato dato) e interazioni (click, input, tastiera, emits). Lo stile di API che scegli cambia quanto frequentemente puoi testare il primo gruppo senza montare un componente completo.
I test Options API tendono a somigliare a “monta il componente, modifica lo stato dell'istanza, assert sul DOM”. Funziona, ma può incoraggiare test più grandi perché la logica è mescolata in methods, computed, watch e hook di lifecycle. Quando qualcosa fallisce, passi tempo a capire se è un timing del watcher, un effetto di lifecycle o la logica stessa.
L'Options API spesso sembra naturale per:
- Flow utente che dipendono dall'ordine dei lifecycle (fetch on mount, reset su cambio rotta)
- Comportamenti guidati da watcher (auto-save, sincronizzazione query)
- Emissione di eventi da metodi del componente (
save(),reset(),applyFilter())
La Composition API sposta l'equilibrio. Se sposti la logica in composables, puoi unit testare quella logica come funzioni semplici, con input e output chiari. Questo riduce il numero di test “monta e clicca” necessari e rende i fallimenti più locali. Rende anche le dipendenze più facili da controllare: invece di mockare un globale, passi una dipendenza (come una funzione di fetch, un formatter di date o un checker di permessi) nel composable.
Un esempio concreto: una AdminTable riutilizzabile con ordinamento, paginazione e righe selezionate. Con la Composition API la logica di selezione può vivere in useRowSelection() e essere testata senza renderizzare la tabella (toggle, clear, select all, preservare attraverso le pagine). Poi mantieni un set ridotto di test dei componenti per confermare che il template colleghi pulsanti, checkbox ed eventi emessi correttamente.
Per mantenere i test piccoli e leggibili (qualunque sia lo stile), costruisci una cucitura chiara tra logica e UI:
- Metti le regole di business in funzioni pure o composables, non in watcher.
- Tieni gli effetti collaterali (fetch, storage, timer) dietro dipendenze iniettate.
- Preferisci pochi test di integrazione focalizzati per componente, non un unico test gigante “tutto insieme”.
- Nomina stati ed eventi in modo coerente in tutta la libreria (riduce setup nei test).
- Evita accoppiamenti nascosti (come il metodo A che dipende dall'esecuzione del watcher B).
Se il tuo obiettivo è una scelta di stile che migliori la stabilità dei test, spingi verso meno comportamenti guidati dal lifecycle e più unità logiche isolate che puoi verificare senza il DOM.
Onboarding dei nuovi contributori: quanto velocemente diventano produttivi
In una grande libreria admin l'onboarding riguarda meno l'insegnare Vue e più l'aiutare le persone a trovare le cose, seguire le stesse convenzioni e sentirsi sicure nel fare modifiche. La maggior parte dei rallentamenti deriva da tre gap: navigazione (dove sta la logica?), convenzioni (come lo facciamo qui?) e fiducia (come cambio questo senza rompere cinque schermate?).
Con l'Options API i nuovi spesso partono più veloci il primo giorno perché la struttura è familiare: props, data, computed, methods, watchers. Il compromesso è che il comportamento reale spesso è sparso. Una singola feature come il “filtering lato server” può essere divisa tra un watcher, un computed e due metodi, più un mixin. Le persone leggono ogni blocco, ma passano tempo a ricomporre la storia.
Con la Composition API il guadagno in onboarding è che la logica correlata può stare insieme: stato, effetti collaterali e helper in un unico posto. Il costo è la literacy sui composables. I nuovi contributori devono capire pattern come useTableState() e come i valori reattivi fluiscono attraverso più composables. Senza confini chiari può sembrare di saltare tra file senza mappa.
Qualche convenzione toglie la maggior parte delle domande, qualunque stile tu scelga:
- Usa una struttura prevedibile:
components/,composables/,types/,tests/. - Scegli un pattern di naming e rispettalo (per esempio:
useX,XTable,XForm). - Aggiungi brevi docblock: cosa fa il componente, props chiave e eventi principali.
- Definisci una regola di “escape hatch” (quando è OK aggiungere un nuovo composable o helper).
- Mantieni un piccolo componente “golden” che dimostri il pattern preferito.
Esempio: se il tuo team genera un pannello admin Vue 3 e poi lo personalizza (per esempio, una web app costruita con AppMaster ed estesa dagli sviluppatori), l'onboarding migliora molto quando c'è un posto ovvio per aggiustare il comportamento della tabella (ordinamento, filtri, paginazione) e un posto ovvio per il wiring UI (slot, renderer di colonne, azioni riga). Quella chiarezza conta più dell'API che scegli.
Passo-passo: scegliere uno stile e introdurlo in sicurezza
Per una grande UI admin, il modo più sicuro per decidere è partire con una feature ben delimitata e trattarla come un pilota, non come un rewrite.
Scegli un modulo con comportamento chiaro e alto riuso, come il filtering della tabella o la validazione dei form. Prima di toccare il codice, annota cosa fa oggi: input (props, parametri query, azioni utente), output (eventi, emits, cambi URL) e edge case (stato vuoto, reset, errori server).
Poi poni i confini. Decidi cosa deve restare dentro il componente (rendering, eventi DOM, dettagli di accessibilità) e cosa può andare nel codice condiviso (parsing dei filtri, debouncing, costruzione dei parametri API, stato di default). Qui molte librerie sbagliano: se sposti decisioni UI nel codice condiviso, lo rendi meno riutilizzabile.
Un piano di rollout pratico:
- Scegli un componente che mostri chiaramente il pattern e sia usato da più schermate.
- Estrai un'unità condivisa (un composable o un helper puro) con una API piccola ed esplicita.
- Aggiungi un test focalizzato per quell'unità, basato su scenari reali admin.
- Rifattorizza il componente scelto end-to-end usando la nuova unità.
- Applica lo stesso pattern a un altro componente per confermare che scala.
Mantieni la API condivisa noiosa e ovvia. Per esempio, un composable useTableFilters() potrebbe accettare filtri iniziali ed esporre filters, apply(), reset() e una funzione toRequestParams(). Evita la “magia” che legge dallo stato globale a meno che non sia già una regola ferma nella tua app.
Dopo il pilota, pubblica una breve linea guida interna con un esempio che i contributori possano copiare. Una regola concreta batte un documento lungo, per esempio: “Tutta la logica di filtering delle tabelle sta in un composable; i componenti legano solo i controlli UI e chiamano apply().”
Prima di espandere l'approccio, usa una semplice definizione di done:
- Il nuovo codice si legge allo stesso modo in due componenti diversi.
- I test coprono la logica condivisa senza montare l'intera UI.
- Un nuovo contributore può cambiare una regola di filtro senza toccare file non correlati.
Se il tuo team costruisce anche portali admin con uno strumento no-code come AppMaster, puoi usare la stessa mentalità pilota lì: scegli un workflow (come approvazioni), definisci i comportamenti e standardizza il pattern prima di scalarlo.
Errori comuni e trappole nelle grandi librerie
I problemi maggiori in una grande libreria raramente riguardano la sintassi. Vengono da piccole decisioni locali che si accumulano e rendono più difficile il riuso, il testing e la manutenzione.
Una trappola comune è mischiare pattern a caso. Se metà della libreria usa Options API e l'altra metà usa Composition API senza regole, ogni nuovo componente diventa un dibattito di stile. Finirai anche con soluzioni duplicate agli stessi problemi (form, tabelle, permessi), scritte in forme diverse. Se permetti entrambi, scrivi una policy chiara: i nuovi componenti usano uno stile, il legacy è modificato solo quando necessario e la logica condivisa vive in un posto concordato.
Un'altra trappola è il “god composable”. Nasce spesso come un utile useAdminPage() o useTable() e lentamente assorbe routing, fetching, caching, selezione, dialog, toast e permessi. Diventa difficile da testare perché una chiamata scatena molti effetti collaterali. Diventa anche difficile da riusare perché ogni schermata ne usa solo il 30%, ma paga la complessità del 100%.
I watcher sono un'altra fonte di problemi. Sono facili da aggiungere quando qualcosa sembra fuori sync, ma i bug di timing emergono dopo (soprattutto con dati async e input debounced). Quando le persone segnalano “a volte mi si perde la selezione”, puoi passare ore a riprodurlo.
Campanelli d'allarme che indicano rotta verso il disordine:
- Un componente funziona solo se usato in un ordine preciso di props ed eventi.
- Un composable legge e scrive stato globale senza renderlo ovvio.
- Più watcher aggiornano lo stesso pezzo di stato.
- I refactor continuano a rompere schermate consumer in modi piccoli.
- I contributori evitano di toccare “quel file” perché è rischioso.
L'ultima trappola è rompere le API pubbliche durante i refactor. In app admin, componenti come tabelle, filtri e campi form si diffondono rapidamente. Rinominare una prop, cambiare un evento emesso o modificare il comportamento di uno slot può rompere di nascosto decine di schermate.
Un approccio più sicuro è trattare le API dei componenti come contratti: depreca invece di cancellare, mantieni shim di compatibilità per un po' e aggiungi semplici test d'uso che montino il componente come lo usano i consumer. Se generi interfacce Vue 3 con strumenti come AppMaster, questo è ancora più importante: contratti di componenti coerenti facilitano il riuso delle schermate e mantengono le modifiche prevedibili.
Controlli rapidi prima di impegnarti in un pattern
Prima di scegliere Composition API, Options API o un mix, fai qualche controllo veloce su componenti reali della tua libreria. L'obiettivo è semplice: rendere facile trovare la logica, riutilizzarla in sicurezza e testare le parti su cui gli admin contano davvero.
1) Qualcuno trova la logica rapidamente?
Apri un componente tipico admin-heavy (filtri + tabella + permessi + azioni in blocco). Fai finta di essere nuovo al codebase.
Un buon segno è quando un contributore può rispondere a “dov'è la logica dei filtri?” o “chi decide se il pulsante è disabilitato?” in meno di 2 minuti. Con Options API di solito questo significa che la logica è chiaramente divisa in computed, methods e watchers. Con Composition API significa che setup() è organizzato in piccoli blocchi nominati (o composables) ed evita una singola funzione gigante.
2) Le utility condivise si comportano come funzioni, non come magia?
Qualunque pattern tu scelga, il codice condiviso dovrebbe avere input e output chiari e pochi effetti collaterali. Se un helper accede allo stato globale, muta oggetti passati o innesca chiamate di rete senza renderlo ovvio, il riuso diventa rischioso.
Controllo rapido:
- Riesci a leggere la firma di un composable o helper e intuire cosa ritorna?
- Puoi usarlo in due componenti senza setup nascosto?
- Puoi resettarne lo stato nei test senza stratagemmi?
3) I tuoi test sono focalizzati sui comportamenti admin?
Le app admin falliscono in modi prevedibili: filtri applicati male, permessi che lasciano azioni visibili, validazioni incoerenti e stato tabella che si rompe dopo modifiche. Invece di testare dettagli di implementazione interni (watchers vs refs), scrivi test attorno al comportamento: “dato il ruolo X, l'azione Y è nascosta”, “il salvataggio mostra errore e mantiene l'input dell'utente”, “il cambio filtro aggiorna la query e il messaggio di stato vuoto”. Questo mantiene i test stabili anche se rifattorizzi tra stili.
4) Avete uno standard per lo stato async?
Le grandi librerie crescono tanti piccoli flow async: carica opzioni, valida campi, fetch righe tabella, retry su fallimento. Se ogni componente inventa il proprio handling loading/error, onboarding e debugging rallentano.
Scegli una forma chiara per lo stato async (loading, error, retries, cancellazione). La Composition API spesso incoraggia un useAsyncX() riutilizzabile, mentre l'Options API può standardizzare uno stato in data() più metodi condivisi. Qualunque sia la scelta, dev'essere coerente.
5) Le API pubbliche dei componenti sono stabili e autoesplicative?
Tratta i componenti come prodotti. Le loro props, eventi emessi e slot sono il contratto. Se quel contratto cambia spesso, ogni schermata admin diventa fragile.
Cerca commenti che spieghino l'intento (non i meccanismi): cosa significano le props, cosa garantiscono gli eventi e cosa è considerato interno. Se costruisci strumenti interni con una piattaforma come AppMaster, la stessa mentalità aiuta: blocchi stabili rendono più veloci le schermate future.
Scenario di esempio e prossimi passi per il tuo team
Immagina una pagina admin “Users” che stai ricostruendo: una barra filtri (status, ruolo, data creazione), una tabella con righe selezionabili, azioni in blocco (disabilita, elimina, esporta) e controllo basato sui ruoli (solo admin può eliminare in blocco, manager può modificare ruoli).
Con Composition API vs Options API, l'interfaccia può essere identica, ma il codice tende a organizzarsi diversamente.
Nell'Options API finisci spesso con un componente grande che ha data per filtri e selezione, computed per stato derivato e methods per fetching, azioni in blocco e controlli di permesso. Il riuso appare come mixin o moduli helper. È familiare, ma la logica correlata può sparirsi (fetching in methods, sync query in watcher, permessi in computed).
Nella Composition API tipicamente dividi la pagina in composables focalizzati: uno per query e filtri, uno per selezione righe e azioni in blocco, e uno per i permessi. Il componente pagina diventa un'assemblaggio di questi pezzi e la logica per ogni preoccupazione resta insieme. Il compromesso è che servono naming e convenzioni di cartelle chiare così i contributori non percepiscono tutto come “magia nello setup”.
Il riuso tende a emergere naturalmente in librerie admin attorno a filtri che si sincronizzano con l'URL, pattern di tabelle lato server (paginazione, ordinamento, select-all, guardie per azioni in blocco), controlli permessi e gating UI (pulsanti, colonne, azioni riga) e stati vuoto/caricamento coerenti.
Un piano di prossimi passi che funziona per la maggior parte dei team:
- Scegli uno stile predefinito per il codice nuovo e consenti eccezioni solo con una motivazione scritta.
- Definisci convenzioni: dove vivono i composables, come si chiamano, cosa possono importare e cosa devono restituire.
- Aggiungi una pagina di riferimento ridotta (come questa Users page) come standard d'oro per pattern e struttura.
- Scrivi test attorno alle parti riutilizzabili prima della UI (filtri, permessi, azioni in blocco), non al layout visivo.
- Se la velocità è più importante della personalizzazione profonda per alcune schermate, considera di generare quelle con uno strumento no-code come AppMaster, lasciando la libreria scritta a mano per le parti davvero uniche.
Se stai già usando AppMaster, aiuta mantenere la stessa mentalità tra parti generate e scritte a mano: contratti di componenti stabili e logica condivisa impacchettata in unità piccole e esplicite. Per i team che valutano il no-code per strumenti interni, AppMaster (appmaster.io) è costruito per generare applicazioni complete (backend, web e mobile) lasciandoti comunque standardizzare una UI Vue 3 dove conta.
Se fai una cosa questa settimana, prendi la Users page come template e falla rispettare nelle code review. Un esempio chiaro vale più di una guida lunga.
FAQ
Default al Composition API se la tua libreria ha comportamenti ripetuti come filtri, paginazione, azioni in blocco e regole di permesso. Rende più semplice estrarre la logica condivisa in composables e mantiene le dipendenze più esplicite. Usa l'Options API quando i componenti sono per lo più presentazionali e la logica è leggera.
L'Options API raggruppa il codice per tipo (data, methods, computed, watch), quindi la logica di una singola feature spesso risulta dispersa. La Composition API tende a raggruppare il codice per feature, così tutto per “filtri” o “selezione” può stare insieme. La scelta migliore è quella che rende la prossima modifica facile da trovare e sicura da applicare.
Con l'Options API il riuso spesso inizia con mixins o extends, che possono nascondere da dove provengono metodi e valori computed e causare collisioni di nomi. Con la Composition API il riuso diventa solitamente composables con input e output chiari, quindi il wiring è visibile nel componente. Per una libreria condivisa, il riuso esplicito tende a rimanere manutenibile più a lungo.
Tratta ogni composable come una micro-API: un solo compito, parametri chiari e ritorni prevedibili. Se un composable inizia a mischiare paginazione, caching, permessi e notifiche, dividilo in parti più piccole. Composables piccoli sono più semplici da testare, riutilizzare e meno inclini a effetti collaterali inattesi.
Mantieni il contratto pubblico stabile: props, eventi emessi e slot dovrebbero cambiare raramente. Metti formattazione dell'input e validazione di base vicino ai componenti di input, ma tieni le regole di business in composables o nei container. In questo modo puoi rifattorizzare internamente senza costringere ogni schermata a cambiare.
La Composition API solitamente facilita il testing unitario della logica senza montare l'intero componente, perché puoi testare direttamente composables e funzioni pure. L'Options API tende a spingere verso test che montano il componente, dove watcher e timing di lifecycle possono aggiungere rumore. Indipendentemente dallo stile, separare le regole di business dal wiring UI è ciò che mantiene i test piccoli e stabili.
Standardizza una forma unica per lo stato async come loading, error, e una strategia chiara per retry o cancellazione. Non permettere che ogni componente inventi convenzioni proprie, perché il debugging diventa lento e incoerente. Puoi implementare lo standard con entrambe le API, l'importante è che sia coerente in tutta la libreria.
L'Options API può essere più semplice il primo giorno perché la struttura è familiare, ma i contributori potrebbero impiegare tempo per ricomporre la logica sparsa in blocchi e mixins. La Composition API può accelerare una volta che le persone conoscono i tuoi composables e le convenzioni di cartelle, perché il comportamento correlato è raggruppato e il riuso è visibile. L'onboarding migliora soprattutto con un singolo componente “golden” e l'applicazione costante dei pattern in code review.
Scegli una feature ben delimitata e ad alto riuso (come il filtering della tabella o il mapping degli errori del form) e trattala come un pilota. Estrai un'unità condivisa con API piccole ed esplicite, scrivi un test mirato, poi rifattorizza un componente end-to-end. Dopo che il pattern funziona in almeno due componenti, puoi estenderlo gradualmente.
Segnali di allarme: duplicati sparsi, catene di watcher che si contrastano, componenti che funzionano solo con un ordine preciso di props/eventi. Altro segnale: frequenti breaking change a props, eventi emessi o comportamenti degli slot. Se i contributori evitano certe file perché sono rischiose, significa che servono contratti più chiari e riuso esplicito.


