Binding per gli Input dei Form
Quando si gestiscono i form nel frontend, spesso è necessario sincronizzare lo stato degli elementi di input del form con il corrispondente stato in JavaScript. Può risultare laborioso collegare manualmente i binding dei valori e i listeners degli eventi di change degli input:
template
<input
:value="text"
@input="event => text = event.target.value">
La direttiva v-model
ci aiuta a semplificare il tutto come segue:
template
<input v-model="text">
Inoltre, v-model
può essere utilizzata su diversi tipi di input, elementi <textarea>
e <select>
. Si espande automaticamente in diverse coppie di proprietà DOM ed eventi in base all'elemento su cui viene utilizzata:
- Gli
<input>
di tipo testo e gli elementi<textarea>
utilizzano la proprietàvalue
e l'eventoinput
; - Gli
<input type="checkbox">
e gli<input type="radio">
utilizzano la proprietàchecked
e l'eventochange
; - Gli elementi
<select>
utilizzanovalue
come prop echange
come evento.
Nota
v-model
ignorerà gli attributi iniziali value
, checked
o selected
trovati su qualsiasi elemento del form. Considererà sempre lo stato JavaScript collegato come unica fonte di verità. Dovresti dichiarare il valore iniziale tramite JavaScript, usando le reactivity APIs.
Utilizzo di Base
Text
template
<p>Il messaggio è: {{ message }}</p>
<input v-model="message" placeholder="edit me" />
Il messaggio è:
Nota
Per le lingue che richiedono un IME (Cinese, Giapponese, Coreano, ecc.), noterai che v-model
non viene aggiornato durante la composizione IME. Se vuoi rispondere anche a questi aggiornamenti, utilizza il tuo listener dell'evento input
e il binding del value
invece di usare v-model
.
Multiline text
template
<span>Il messaggio su più righe è:</span>
<p style="white-space: pre-line;">{{ message }}</p>
<textarea v-model="message" placeholder="aggiungi più righe"></textarea>
Il messaggio su più righe è:
Nota che l'interpolazione all'interno di <textarea>
non funzionerà. Utilizza v-model
al suo posto.
template
<!-- sbagliato -->
<textarea>{{ text }}</textarea>
<!-- corretto -->
<textarea v-model="text"></textarea>
Checkbox
Checkbox singola con valore booleano:
template
<input type="checkbox" id="checkbox" v-model="checked" />
<label for="checkbox">{{ checked }}</label>
Possiamo collegare anche più checkbox allo stesso array o valore Set:
js
const checkedNames = ref([])
template
<div>Nomi selezionati: {{ checkedNames }}</div>
<input type="checkbox" id="jack" value="Jack" v-model="checkedNames">
<label for="jack">Jack</label>
<input type="checkbox" id="john" value="John" v-model="checkedNames">
<label for="john">John</label>
<input type="checkbox" id="mike" value="Mike" v-model="checkedNames">
<label for="mike">Mike</label>
Nomi selezionati: []
In questo caso, l'array checkedNames
conterrà sempre i valori delle caselle attualmente selezionate.
Radio
template
<div>Scelto: {{ picked }}</div>
<input type="radio" id="one" value="One" v-model="picked" />
<label for="one">One</label>
<input type="radio" id="two" value="Two" v-model="picked" />
<label for="two">Two</label>
Scelto:
Select
Select singola:
template
<div>Selezionato: {{ selected }}</div>
<select v-model="selected">
<option disabled value="">Please select one</option>
<option>A</option>
<option>B</option>
<option>C</option>
</select>
Selezionato:
Nota
Se il valore iniziale della tua espressione v-model
non corrisponde a nessuna delle opzioni, l'elemento <select>
verrà visualizzato in uno stato "non selezionato". Su iOS, questo impedirà all'utente di selezionare la prima voce, poiché il iOS non scatena un evento di modifica in tale situazione. Per questo è consigliabile fornire un'opzione disabilitata con un valore vuoto, come mostrato nell'esempio precedente.
Select multiple (legate ad un array):
template
<div>Selezionato: {{ selected }}</div>
<select v-model="selected" multiple>
<option>A</option>
<option>B</option>
<option>C</option>
</select>
Selezionato: []
Le opzioni della select possono essere rese dinamicamente con v-for
:
js
const selected = ref('A')
const options = ref([
{ text: 'One', value: 'A' },
{ text: 'Two', value: 'B' },
{ text: 'Three', value: 'C' }
])
template
<select v-model="selected">
<option v-for="option in options" :key="option.value" :value="option.value">
{{ option.text }}
</option>
</select>
<div>Selezionato: {{ selected }}</div>
Binding dei Value
Per radio, checkbox e le option delle select, i valori di binding per v-model
sono solitamente stringhe statiche (o booleani per le checkbox):
template
<!-- `picked` è una stringa "a" quando è selezionata -->
<input type="radio" v-model="picked" value="a" />
<!-- `toggle` è true o false -->
<input type="checkbox" v-model="toggle" />
<!-- `selected` è una stringa "abc" quando la prima option è selezionata -->
<select v-model="selected">
<option value="abc">ABC</option>
</select>
In alcuni casi potremmo voler collegare il valore a una proprietà dinamica sull'istanza attiva corrente. Possiamo usare v-bind
per raggiungere questo obiettivo. Inoltre, utilizzando v-bind
, possiamo collegare il valore dell'input a valori che non sono stringhe.
Checkbox
template
<input
type="checkbox"
v-model="toggle"
true-value="yes"
false-value="no" />
true-value
e false-value
sono attributi specifici di Vue che funzionano solo con v-model
. In questo caso, il valore della proprietà toggle
verrà impostato su 'yes'
quando la casella è selezionata, e su 'no'
quando non è selezionata. Puoi anche collegarli a valori dinamici utilizzando v-bind
:
template
<input
type="checkbox"
v-model="toggle"
:true-value="dynamicTrueValue"
:false-value="dynamicFalseValue" />
Suggerimento
Gli attributi true-value
e false-value
non influenzano l'attributo value
dell'input, poiché i browser non includono le caselle non selezionate nell'invio dei form. Per garantire che uno dei due valori venga inviato in un form (ad esempio "sì" o "no"), utilizza invece gli input radio.
Radio
template
<input type="radio" v-model="pick" :value="first" />
<input type="radio" v-model="pick" :value="second" />
pick
sarà impostato al valore di first
quando il primo input radio è selezionato, e sarà impostato al valore di second
quando viene selezionato il secondo.
Opzioni delle Select
template
<select v-model="selected">
<!-- oggetto letterale inline -->
<option :value="{ number: 123 }">123</option>
</select>
v-model
supporta anche il binding di valori non-stringa! Nell'esempio sopra, quando l'opzione è selezionata, selected
sarà impostato al valore dell'oggetto letterale { number: 123 }
.
Modificatori
.lazy
Di default, v-model
sincronizza l'input con i dati dopo ogni evento input
(con l'eccezione della composizione IME come indicato sopra). Aggiungendo il modificatore lazy
, la sincronizzazione avviene dopo gli eventi change
, anziché dopo ogni evento input
:
template
<!-- Sincronizzati dopo "change" al posto di "input" -->
<input v-model.lazy="msg" />
.number
Se desideri che l'input dell'utente venga automaticamente convertito in un numero, puoi aggiungere il modificatore number
agli input gestiti da v-model
:
template
<input v-model.number="age" />
Se il valore non può essere interpretato con parseFloat()
, verrà allora utilizzato il valore originale.
Il modificatore number
viene applicato automaticamente se l'input ha type="number"
.
.trim
Se vuoi che gli spazi bianchi inseriti dall'utente vengano rimossi automaticamente, puoi aggiungere il modificatore trim
agli input gestiti da v-model
:
template
<input v-model.trim="msg" />
v-model
con i Componenti
Se non sei ancora familiare con i componenti di Vue, puoi saltare questa parte per ora.
I tipi di input integrati in HTML potrebbero non soddisfare sempre le tue esigenze. Fortunatamente, i componenti Vue ti permettono di costruire input riutilizzabili con un comportamento completamente personalizzato. Questi input funzionano anche con v-model
! Per saperne di più, leggi la sezione Utilizzo con v-model
nella guida ai Componenti.