È uscito il Corso Java Completo
Torna al blog

Cos'è Vue e come funziona

Cos'è Vue e come funziona: framework progressivo, Single File Component, reattività con ref e reactive, Composition API, direttive e quando conviene davvero.

Edoardo Midali

Edoardo Midali

Developer · Content Creator

10 min di lettura

Hai un sito che funziona, magari fatto in HTML e un po' di jQuery, e ti serve rendere interattiva una sola parte: un filtro, un configuratore, un carrello. Riscrivere tutto in un framework sembra sproporzionato, ma continuare a manipolare il DOM a mano sta diventando un incubo. Vue nasce esattamente per questo punto intermedio. In questo articolo trovi cosa sono i Single File Component, come funziona la reattività, cosa scegliere tra Composition API e Options API e quando Vue non è la scelta giusta.

Cos'è

Vue è un framework JavaScript progressivo per costruire interfacce: puoi aggiungerlo a una singola pagina esistente con un tag script, oppure usarlo come base di un'applicazione intera, senza cambiare strumento in mezzo.

Quella parola, "progressivo", è la caratteristica che lo distingue davvero. Vale la pena capirla prima di tutto il resto.

Progressivo: cosa significa in pratica

Quasi tutti i framework a componenti presuppongono che tu stia costruendo un'applicazione da zero: installi il progetto, configuri la build, e da quel momento tutto passa da lì. Se hai un sito esistente, l'adozione è un tutto-o-niente.

Vue è pensato per essere adottato a strati. Il livello più basso è questo: includi la libreria e monti Vue su un pezzo di pagina, lasciando il resto com'è.

<div id="filtro">
  <input v-model="cerca" placeholder="Cerca un prodotto" />
  <p>Stai cercando: {{ cerca }}</p>
</div>

<script type="module">
  import { createApp, ref } from "https://unpkg.com/vue@3/dist/vue.esm-browser.js";

  createApp({
    setup() {
      const cerca = ref("");
      return { cerca };
    },
  }).mount("#filtro");
</script>

Nessuna build, nessuna cartella di progetto, nessun passaggio a un altro modo di lavorare. Il resto del sito non sa nemmeno che Vue esiste.

Il livello successivo è aggiungere uno strumento di build e i file .vue, poi il router ufficiale, poi la gestione dello stato, poi eventualmente Nuxt. Sono passaggi separati e ognuno è reversibile, invece di un unico salto iniziale.

È il motivo per cui Vue viene scelto spesso quando c'è già un progetto vivo — un backend in PHP, Laravel, Rails, Django — e non lo si vuole riscrivere per avere interattività in tre pagine.

I Single File Component

Quando passi al livello "applicazione", il formato che usi è il file .vue. Contiene le tre parti di un componente nello stesso file, ognuna nel suo blocco.

<script setup>
import { ref } from "vue";

const contatore = ref(0);
</script>

<template>
  <button @click="contatore++">Cliccato {{ contatore }} volte</button>
</template>

<style scoped>
button {
  padding: 0.5rem 1rem;
  border-radius: 6px;
}
</style>

Tre osservazioni, perché è qui che si vede la filosofia dello strumento.

Il template è HTML vero, non una sintassi che gli assomiglia: è HTML valido con attributi in più. Chi arriva dal web tradizionale lo legge subito, e i designer che toccano il markup non devono imparare un linguaggio nuovo.

Lo stile è nel componente, e scoped lo isola, così le regole CSS valgono solo lì senza dover inventare convenzioni di nomi per evitare collisioni. Sembra una cosa piccola e in un progetto grande ti risparmia parecchi grattacapi.

L'obiezione classica è "ma non si dovevano tenere HTML, CSS e JavaScript separati?". La risposta di Vue è che quei tre pezzi, quando riguardano lo stesso componente, sono la stessa responsabilità: separarli significa aprire tre file per capire un pulsante.

La reattività: ref e reactive

Qui c'è la differenza di funzionamento più concreta rispetto a React, ed è quella che si sente tutti i giorni.

ref crea un valore reattivo. Dentro lo script lo leggi e lo scrivi tramite .value; nel template il .value è automatico.

<script setup>
import { ref, computed } from "vue";

const prezzo = ref(100);
const quantita = ref(2);

const totale = computed(() => prezzo.value * quantita.value);

function raddoppia() {
  quantita.value = quantita.value * 2;
}
</script>

<template>
  <p>Totale: {{ totale }} €</p>
  <button @click="raddoppia">Raddoppia</button>
</template>

reactive fa la stessa cosa ma su un oggetto intero, senza .value:

import { reactive } from "vue";

const form = reactive({ nome: "", email: "" });
form.nome = "Edoardo"; // reattivo

Il punto interessante è cosa succede quando cambi un valore. Vue tiene traccia, durante il render, di quali dati ogni pezzo di interfaccia ha letto. Quando quantita cambia, Vue sa già chi dipende da quantita e aggiorna solo quello: non ricalcola il componente per confrontarlo con la versione precedente, va dove serve.

La conseguenza pratica è che in Vue non passi tempo a ottimizzare i render. In React esiste un intero capitolo di memorizzazione — memo, useMemo, useCallback — per dire alla libreria quando non rifare il lavoro. In Vue quel capitolo non c'è. Il confronto tra i tre è in React, Vue o Angular.

E computed è un valore derivato che si ricalcola solo quando cambia una sua dipendenza: risolve alla radice il problema di duplicare informazioni nello stato.

Composition API e Options API

Trovi in giro due stili di scrittura molto diversi e questo confonde chi inizia. Vale la pena chiarirlo una volta.

La Options API è lo stile storico: il componente è un oggetto con sezioni predefinite.

export default {
  data() {
    return { contatore: 0 };
  },
  computed: {
    doppio() {
      return this.contatore * 2;
    },
  },
  methods: {
    incrementa() {
      this.contatore++;
    },
  },
};

La Composition API è quella che hai visto sopra con <script setup>: dichiari tutto come normale codice JavaScript, senza sezioni obbligate.

Options APIComposition API
OrganizzazionePer tipo (dati, metodi, calcolati)Per argomento logico
Riuso della logicaMixin, fragiliFunzioni normali (composables)
TypeScriptFunziona a faticaNaturale
Primo impattoPiù guidatoRichiede sapere JavaScript
Su componenti grandiLogica sparsa in più sezioniTenuta insieme

Su un progetto nuovo, oggi, usa la Composition API con <script setup>. È la direzione dello strumento, funziona meglio con TypeScript e risolve un problema reale: in un componente grande scritto con la Options API, la logica di una singola funzionalità finisce spezzata su quattro sezioni diverse.

L'Options API resta supportata e non è deprecata — esiste una quantità enorme di codice scritto così — ma non è il modo consigliato per il codice nuovo.

Le direttive

Le direttive sono gli attributi speciali del template. Sono poche e coprono quasi tutto quello che serve.

<template>
  <p v-if="utente">Ciao {{ utente.nome }}</p>
  <p v-else>Non sei collegato</p>

  <ul>
    <li v-for="prodotto in prodotti" :key="prodotto.id">
      {{ prodotto.nome }} — {{ prodotto.prezzo }} €
    </li>
  </ul>

  <input v-model="messaggio" />
  <button @click="invia" :disabled="!messaggio">Invia</button>
</template>

: è la forma breve di v-bind (lega un valore a un attributo), @ è la forma breve di v-on (ascolta un evento).

v-model merita una nota a parte. È il collegamento a doppio senso tra un campo del modulo e una variabile: scrivi nell'input e la variabile cambia, cambi la variabile e l'input si aggiorna. In React servono due pezzi scritti a mano ogni volta — il valore e il gestore dell'evento — e su un modulo con quindici campi la differenza si sente.

Il rovescio della medaglia è che il doppio senso nasconde il flusso dei dati: quando un valore cambia e non capisci chi l'ha toccato, di solito è colpa di un v-model messo dove serviva un flusso esplicito.

L'ecosistema ufficiale

Questa è la seconda differenza rilevante rispetto a React, e non è tecnica: è organizzativa.

  • Vue Router — la navigazione tra pagine
  • Pinia — la gestione dello stato condiviso
  • Vite — lo strumento di build, nato nello stesso ambiente
  • Nuxt — il meta-framework, con rendering lato server e generazione statica

Sono mantenuti dallo stesso gruppo, con documentazione unica e versioni coerenti. Il valore non è la qualità tecnica — anche le librerie React equivalenti sono ottime — ma il fatto che la scelta non c'è. In React devi decidere router, gestore dei dati remoti e strumento per i moduli quando ancora non hai l'esperienza per valutarli. Su Vue apri la documentazione e trovi la risposta.

La differenza di fondo sta in cos'è un framework e cos'è una libreria.

Errori comuni che fanno perdere ore

Dimenticare .value nello script. Nel template è implicito, nello script no: scrivi contatore + 1 invece di contatore.value + 1 e ottieni un NaN senza nessun errore. È il primo scoglio di chiunque inizi.

Destrutturare un oggetto reactive. La reattività sta nell'oggetto, non nei valori estratti:

const stato = reactive({ conteggio: 0 });
const { conteggio } = stato; // reattività persa, silenziosamente

Usa toRefs(stato) se ti serve destrutturare, oppure usa ref fin dall'inizio. La regola pratica che risolve il novanta per cento dei casi: usa ref quasi sempre, reactive solo quando hai un oggetto che resta unito.

Usare l'indice come key in v-for. Stesso problema che in React: quando riordini o cancelli elementi, i campi di testo si scambiano il contenuto. Usa un identificativo stabile.

Mutare una prop. Le proprietà che arrivano dal genitore sono in sola lettura. Vue avvisa in console, ma chi non legge la console passa un pomeriggio a cercare un bug fantasma.

Modificare il DOM a mano. Se vieni da jQuery la tentazione è forte, ma al render successivo Vue riscrive tutto e la tua modifica sparisce. Vale la pena chiarire prima cos'è il DOM e chi lo controlla.

Quando Vue è la scelta giusta e quando no

Ha senso quando hai un progetto esistente da rendere interattivo senza riscriverlo, quando il team viene dal web tradizionale, quando vuoi essere produttivo in fretta, o quando l'applicazione è grande e non vuoi passare le giornate a capire perché un componente si ridisegna.

Non è la scelta giusta quando cerchi lavoro come frontend in Italia. Va detto senza girarci intorno: le offerte che chiedono Vue sono una frazione di quelle che chiedono React, e la qualità tecnica non cambia il dato di mercato. Vale anche al contrario: se devi assumere, trovi molte più persone che conoscono React.

E non serve affatto per un sito vetrina o un blog: pagheresti peso e complessità senza ricevere niente. Il criterio resta "questa pagina ha uno stato che cambia molto mentre la si usa?".

In sintesi

Vue è progressivo, e questa è la sua caratteristica distintiva: lo aggiungi a una pagina esistente con un tag script, oppure ci costruisci un'applicazione intera, con gli stessi concetti e senza passaggi traumatici.

I Single File Component tengono template, logica e stile nello stesso file, con il CSS isolato al componente e un template che è HTML leggibile da chiunque.

La reattività funziona per dipendenze: Vue sa quali dati usa ogni pezzo di interfaccia e aggiorna solo quello, quindi non passi tempo a ottimizzare i render a mano.

Oggi si scrive con la Composition API e <script setup>. L'Options API resta valida per il codice esistente, ma non è la direzione.

Avere router e gestione dello stato ufficiali toglie decisioni, e per chi inizia è un vantaggio più grande di quanto sembri.

L'onestà finale è sul mercato: in Italia si lavora molto più con React. Vue è più piacevole da usare, React apre più porte.

Per capire come si confronta con gli altri due nel dettaglio, vedi React, Vue o Angular. Per inquadrare la scelta dentro il progetto completo, come scegliere lo stack per una web app.