Passa al contenuto

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'evento input;
  • Gli <input type="checkbox"> e gli <input type="radio"> utilizzano la proprietà checked e l'evento change;
  • Gli elementi <select> utilizzano value come prop e change 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 l'opzione datale 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([])
js
export default {
  data() {
    return {
      checkedNames: []
    }
  }
}
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' }
])
js
export default {
  data() {
    return {
      selected: 'A',
      options: [
        { 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.

Binding per gli Input dei Form has loaded