Skip to content

Tutto per WordPress, lo sviluppo web — e non solo

⚡ Imparare le basi di Vue 3: da una cartella vuota ai componenti

⚡ Imparare le basi di Vue 3: da una cartella vuota ai componenti

Stai valutando Vue 3 e vedi un framework frontend elegante, uno dei tre grandi. React, Angular, Vue: sembra roba seria. Poi apri il primo tutorial e ti trovi davanti vite, create-vue e file .vue con transpiler… Anche se in realtà puoi includere Vue con una singola riga <script> e iniziare subito a scrivere codice. Niente bundler, niente JSX, niente inferno di configurazione.

La distanza tra «voglio provarlo» e «ho scritto un componente» qui è più breve che altrove. Ma la maggior parte dei tutorial non colma questa distanza: ripropongono la documentazione a frammenti senza darti il quadro completo. Vedi pezzi di sintassi sparsi e non riesci a capire come si trasformino in un'applicazione.

Questa guida è il percorso esatto che abbiamo seguito noi con Vue: da una cartella vuota fino ai componenti con props. Scriverai ed eseguirai ogni riga personalmente. Nessuna magia, solo codice funzionante e la comprensione della reattività, il vero superpotere di Vue.

💡 Panoramica rapida:

  • Costruire un'app Vue da una CDN e montarla sul DOM: la tua prima istanza funzionante in 5 minuti
  • Esaminare quattro direttive chiave, v-for, v-if, v-on e v-bind: i pilastri di ogni template Vue
  • Analizzare computed e methods: quando usare la cache e quando chiamare
  • Estrarre la logica in componenti e passare dati tramite props: un passo verso un'architettura reale

Creare un'app Vue

Partiamo da zero assoluto. Niente create-vue, vite o vue-cli, solo una cartella con due file.

Crea la directory e i file nel terminale:

1mkdir vue3-intro
2cd vue3-intro
3touch index.html app.js

Oppure fai la stessa cosa tramite il file manager. Ora apri index.html e scrivi lo scheletro:

1<!DOCTYPE html>
2<html lang="ru">
3<head>
4 <meta charset="UTF-8">
5 <meta name="viewport" content="width=device-width, initial-scale=1.0">
6 <script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
7 <title>Vue 3 — first steps</title>
8</head>
9<body>
10 <div id="app"></div>
11 <script src="./app.js"></script>
12</body>
13</html>

Tre righe fondamentali. <script src="https://unpkg.com/vue@3/dist/vue.global.js"> carica Vue 3 da una CDN. È il modo più veloce per iniziare: la libreria si carica come un normale file JavaScript, senza bisogno di un passo di build. <div id="app"> definisce il punto di mount: il punto del DOM in cui Vue «vivrà». La terza riga importa app.js, dove definiremo la logica.

Ora riempiamo app.js:

1const app = Vue.createApp({
2 data() {
3 return {
4 course: 'Introduction to Vue 3'
5 }
6 }
7})
8
9app.mount('#app')

Il metodo Vue.createApp() crea un'istanza dell'applicazione. Riceve un oggetto di opzioni; qui abbiamo dichiarato una proprietà course tramite la funzione data(). Vue rende reattiva ogni proprietà restituita da data(): quando un valore cambia, il DOM si aggiorna automaticamente. Nessuna manipolazione manuale dell'albero necessaria.

Ma l'applicazione deve essere «agganciata» a un elemento nella pagina. È ciò che fa app.mount('#app'). Senza questa riga, Vue non reagirà a nessun cambiamento: l'istanza è creata ma non avviata.

Non resta che mostrare la proprietà nell'HTML. All'interno di <div id="app">, scrivi:

1<h1>{{ course }}</h1>

Le doppie parentesi graffe {{ }} sono l'interpolazione, il modo principale per mostrare dati nei template Vue. Tutto ciò che è dentro {{ }} viene sostituito da Vue con il valore della proprietà corrispondente in data().

Prima app Vue 3 nel browser

Apri index.html nel browser. La pagina mostra il testo. La tua prima app è pronta, e l'hai scritta tu invece di generarla tramite una CLI.

Renderizzare liste

In un'applicazione reale, lavori quasi sempre con array: prodotti, tag, post. Vue fornisce la direttiva v-for per questo.

Aggiungiamo un array di tag a data():

1const app = Vue.createApp({
2 data() {
3 return {
4 course: 'Introduction to Vue 3',
5 description: 'Basic guide to Vue 3 for beginners',
6 price: '$19.99',
7 tags: ['Vue', 'Frontend', 'JavaScript']
8 }
9 }
10})

E nell'HTML, una lista:

1<ul>
2 <li v-for="tag in tags">{{ tag }}</li>
3</ul>

La direttiva v-for itera sull'array tags e crea un <li> dedicato per ogni elemento. La variabile tag all'interno del ciclo è l'elemento corrente. Il risultato appare così:

Lista di tag Vue 3 con la direttiva v-for

Una sfumatura importante: quando si itera su un array, ogni elemento del DOM ha bisogno di una chiave univoca. Vue la usa per tracciare l'identità dei nodi durante gli aggiornamenti, il che velocizza il re-rendering e previene bug legati allo stato.

1<ul>
2 <li v-for="(tag, index) in tags" :key="index">{{ tag }}</li>
3</ul>

:key è l'abbreviazione di v-bind:key, che associa l'attributo key al valore dell'indice. Se hai un array di oggetti, ad esempio { id: 1, name: 'Vue' }, usa id come chiave invece dell'indice. L'indice cambia quando l'ordine viene modificato, mentre id è stabile, il che lo rende più affidabile.

Rendering condizionale

Spesso devi mostrare o nascondere un elemento in base a una condizione: un pulsante di acquisto solo se il corso è disponibile. Vue gestisce questa esigenza con la direttiva v-if.

Aggiungiamo un flag available a data():

1data() {
2 return {
3 course: 'Introduction to Vue 3',
4 description: 'Basic guide to Vue 3 for beginners',
5 price: '$19.99',
6 available: true,
7 tags: [
8 { id: 1, name: 'Vue' },
9 { id: 2, name: 'Frontend' },
10 { id: 3, name: 'JavaScript' }
11 ]
12 }
13}

E usiamolo nel markup:

1<p v-if="available">Course available for purchase!</p>
2<p v-else>Unfortunately, the course is currently unavailable.</p>

v-if valuta l'espressione tra virgolette. Se è truthy, viene renderizzato il primo blocco; altrimenti, entra in gioco v-else. Prova a eseguire app.available = false nella console del browser e guarda la pagina reagire all'istante.

Rendering condizionale in Vue 3 con v-if

Oltre a v-if / v-else, esistono anche v-else-if per catene di condizioni e v-show. La differenza è fondamentale: v-if rimuove completamente l'elemento dal DOM, mentre v-show si limita ad attivare display: none. Scegli v-if quando la condizione cambia raramente. Usa v-show per toggle frequenti come le tab, dove le performance contano.

Gestione degli eventi

La direttiva v-on, o @ in forma abbreviata, resta in ascolto degli eventi del DOM: click, input, hover. Quando un evento si verifica, Vue esegue il metodo o l'espressione specificata.

Aggiungiamo un metodo purchase alle opzioni dell'app:

1const app = Vue.createApp({
2 data() {
3 return {
4 course: 'Introduction to Vue 3',
5 description: 'Basic guide to Vue 3 for beginners',
6 price: '$19.99',
7 available: true,
8 tags: [
9 { id: 1, name: 'Vue' },
10 { id: 2, name: 'Frontend' },
11 { id: 3, name: 'JavaScript' }
12 ]
13 }
14 },
15 methods: {
16 purchase() {
17 console.log('Course purchased!')
18 }
19 }
20})

La sezione methods contiene funzioni accessibili nel template e in altri metodi tramite this. Ora colleghiamo la chiamata a un pulsante:

1<button @click="purchase">Buy</button>
Gestire un click in Vue 3 con v-on

Per azioni semplici, puoi scrivere il codice direttamente in @click:

1<button @click="available = !available">Toggle availability</button>
Attivare/disattivare lo stato del pulsante in Vue 3

Il codice inline come questo è comodo per operazioni brevi, come attivare o disattivare un flag. Ma la logica complessa va sempre spostata nei metodi; il template deve restare leggibile. Una regola semplice: counter += 1 va bene nel template, ma dieci righe di logica di acquisto appartengono a un metodo.

Binding degli attributi

Attributi come src, href o alt spesso devono essere dinamici. La direttiva v-bind, o : in forma abbreviata, lega il valore di un attributo a un'espressione Vue.

Aggiungiamo i dati per un'immagine:

1data() {
2 return {
3 // ...other properties
4 imgURL: 'https://catalins.tech/img',
5 imgDescription: 'Photo of a desk with a computer'
6 }
7}

Nel template, li colleghiamo a un <img>:

1<img :src="imgURL" :alt="imgDescription" width="500" height="350">

La forma estesa sarebbe v-bind:src="imgURL"; i due punti sono semplicemente zucchero sintattico. Vue ora traccia imgURL e imgDescription: modificali in data() e l'immagine nella pagina si aggiorna automaticamente. Questa è la reattività in azione.

Associare attributi immagine con v-bind

Lo stesso principio si applica ad attributi come :href, :disabled e :class, così come a tutti gli altri. Prova tu stesso: aggiungi un link con un href dinamico preso da data() e verifica che funzioni senza una sola riga di codice aggiuntiva.

Proprietà computed

A volte i dati devono essere trasformati prima di essere mostrati: formattare un prezzo, concatenare nome e cognome, verificare una condizione. Vue mette a disposizione le proprietà computed per questo.

Immagina di voler sempre avere una descrizione per l'immagine, anche se il campo imgDescription è vuoto. Scriviamo una proprietà computed:

1const app = Vue.createApp({
2 data() {
3 return {
4 course: 'Introduction to Vue 3',
5 description: 'Basic guide to Vue 3 for beginners',
6 price: '$19.99',
7 available: true,
8 imgURL: 'https://catalins.tech/img',
9 imgDescription: 'Photo of a desk with a computer',
10 tags: [
11 { id: 1, name: 'Vue' },
12 { id: 2, name: 'Frontend' },
13 { id: 3, name: 'JavaScript' }
14 ]
15 }
16 },
17 computed: {
18 hasImageDescription() {
19 return this.imgDescription.length > 0
20 ? this.imgDescription
21 : 'Automatic image description'
22 }
23 }
24})

Ora usa la proprietà computed nel template al posto del dato grezzo:

1<img :src="imgURL" :alt="hasImageDescription" width="500" height="350">

Vue memorizza nella cache il risultato di una proprietà computed e lo ricalcola solo quando le sue dipendenze cambiano, nel nostro caso imgDescription. Questo è più efficiente che chiamare una funzione a ogni render.

Una regola importante: le proprietà computed servono per mostrare dati, non per modificarli. Non alterare lo stato dell'applicazione dentro computed; per quello usa i metodi.

Metodi vs. proprietà computed

La differenza tra methods e computed si riduce a una domanda: stai modificando dati o mostrando un valore derivato?

Le proprietà computed appartengono al livello di presentazione. Formattazione, filtri, controlli di condizioni, concatenazione di stringhe. Sono memorizzate nella cache e non hanno effetti collaterali.

I metodi servono per le azioni. Modificare un valore in data(), inviare una richiesta, attivare un flag. Vengono chiamati esplicitamente e possono fare qualsiasi cosa.

Un tipico anti-pattern è modificare this.course dentro una proprietà computed. Una proprietà computed reagisce ai cambiamenti di course ma non dovrebbe modificarlo direttamente. Usa sempre un metodo per modificare i dati. Lascia che il template descriva «cosa mostrare», non «come calcolarlo».

Componenti e props

Quando un'applicazione cresce, tenere tutto in un unico file diventa ingestibile. Vue permette di suddividere l'interfaccia in componenti: blocchi isolati con la propria logica, template e stili.

Creiamo il nostro primo componente, CourseCard:

1mkdir components
2touch components/CourseCard.js

In components/CourseCard.js, definiamo il componente:

1app.component('coursedisplay', {
2 data() {
3 return {
4 course: 'Introduction to Vue 3',
5 description: 'Basic guide to Vue 3 for beginners',
6 price: '$19.99',
7 available: true,
8 imgURL: 'https://catalins.tech/img',
9 imgDescription: 'Photo of a desk with a computer',
10 tags: [
11 { id: 1, name: 'Vue' },
12 { id: 2, name: 'Frontend' },
13 { id: 3, name: 'JavaScript' }
14 ]
15 }
16 },
17 computed: {
18 hasImageDescription() {
19 return this.imgDescription.length > 0
20 ? this.imgDescription
21 : 'Automatic image description'
22 }
23 },
24 template: `
25 <img :src="imgURL" :alt="hasImageDescription" width="500" height="350">
26 <h1>{{ course }}</h1>
27 <p>{{ description }}</p>
28 <p>{{ price }}</p>
29 <button @click="available = !available">Buy</button>
30 <ul>
31 <li v-for="tag in tags" :key="tag.id">{{ tag.name }}</li>
32 </ul>
33 <p v-if="available">Course available for purchase!</p>
34 <p v-else>Unfortunately, the course is currently unavailable.</p>
35 `
36})

Il primo argomento di app.component() è il nome che useremo nell'HTML come tag: <coursedisplay></coursedisplay>. Il secondo è un oggetto con data(), computed e template, gli "interni" del componente.

Ora includiamo il componente in index.html e usiamolo:

1<div id="app">
2 <coursedisplay></coursedisplay>
3</div>
4<script src="./app.js"></script>
5<script src="./components/CourseCard.js"></script>
6<script>
7 const mountedApp = app.mount('#app')
8</script>

Abbiamo importato il file del componente, lo abbiamo usato come tag personalizzato e montato l'applicazione direttamente nell'HTML. La logica del corso ora è incapsulata dentro CourseCard, mentre app.js si occupa solo di creare l'istanza.

Props: passare dati tra componenti

Le props (abbreviazione di properties) sono il meccanismo per passare dati da un componente padre a un figlio. Il componente figlio dichiara quali props accetta e il padre le passa come attributi.

Aggiungiamo una prop paid a CourseCard che indica se il corso è a pagamento o gratuito:

1app.component('coursedisplay', {
2 props: {
3 paid: {
4 type: Boolean
5 }
6 },
7 // ...rest of the configuration
8})

Il padre, nel nostro caso app.js, passa il valore:

1const app = Vue.createApp({
2 data() {
3 return {
4 allCourses: 1,
5 paid: true
6 }
7 }
8})

E in index.html, passiamo la prop tramite:

1<coursedisplay :paid="paid"></coursedisplay>

Vue convalida automaticamente il tipo del valore passato. Se ci si aspetta un Boolean ma arriva una stringa, il framework emette un avviso nella console. Questo evita errori banali quando la codebase cresce.

Per rendere una prop obbligatoria, si aggiunge required: true alla sua definizione. Vue segnalerà se il padre non passa un valore, così da scoprire il problema prima che rompa l'interfaccia.

Il codice completo di questa guida è disponibile nella repository vue3-intro su GitHub, che contiene i file finiti index.html, app.js e components/CourseCard.js. Fai un fork e sperimenta.

Video correlato

Per consolidare il materiale con la pratica, guarda la prima lezione del corso Vue 3 di Net Ninja; completa bene questa guida con una sessione di codice dal vivo:

⁉️🤔 Domande frequenti

Posso usare Vue 3 senza un bundler in produzione?

Sì, includerlo via CDN (unpkg.com/vue@3/dist/vue.global.js) funziona anche in produzione. Ma per progetti reali consigliamo di passare a Vite: si ottengono tree-shaking, code-splitting e Single-File Components, che semplificano drasticamente lo sviluppo quando l'applicazione cresce. Il template iniziale npm create vue@latest configura tutto questo in un minuto.

Che differenza c'è tra v-if e v-show?

v-if rimuove completamente l'elemento dal DOM quando la condizione è falsa. v-show mantiene l'elemento nel DOM ma commuta la proprietà CSS display: none. Usa v-if quando la condizione cambia raramente, ad esempio il ruolo utente. Usa v-show per commutazioni frequenti come le tab, dove la velocità di rendering conta e vuoi evitare di ricreare i nodi.

:key è obbligatorio in v-for?

Tecnicamente v-for funziona senza :key, ma Vue emette un avviso nella console. Senza una chiave, il framework non può tracciare quale elemento del DOM corrisponde a quale dato, causando bug durante il riordino e la cancellazione. Specifica sempre :key con un identificatore univoco, l'id dei tuoi dati anziché l'indice dell'array.

Qual è la differenza tra data() e computed?

data() memorizza lo stato originale, i dati "grezzi". computed ne deriva un valore per la visualizzazione: una stringa formattata, un array filtrato, un risultato di validazione. Una proprietà computed si aggiorna automaticamente quando le sue dipendenze cambiano ed è memorizzata nella cache tra un render e l'altro. I metodi, invece, vengono chiamati ogni volta da capo e sono pensati per azioni, non per la visualizzazione.

Si possono mescolare Options API e Composition API?

Sì, puoi usare entrambi gli stili in un singolo progetto. Vue 3 supporta pienamente le Options API, mentre la Composition API è uno strumento aggiuntivo per scenari complessi. Per imparare, consigliamo di partire dalle Options API: sono più strutturate e più vicine al modello mentale "un componente è un oggetto con opzioni".

Cosa fare dopo: il tuo prossimo passo con Vue 3

Hai costruito la tua prima app, esplorato direttive, proprietà computed e componenti. Questa è la base su cui si costruisce qualsiasi progetto, da una landing page a un pannello di amministrazione.

Ci sono tre percorsi possibili. Primo, consolidare con la pratica: prendi un'API pubblica come JSONPlaceholder e mostra una lista di post con filtri tramite computed. Secondo, passare a Vite e ai file .vue: la documentazione ufficiale di Vue 3 ti guida da create-vue al tuo primo SFC in un'ora. Terzo, impara Vue Router e Pinia per costruire una SPA completa.

Se vuoi provare Vue senza alcuna installazione, consulta l'articolo su come includere Vue via CDN. Il codice di partenza di questa guida si trova nel repository vue3-intro; fai un fork e sperimenta.