Passer au contenu

Liaisons des entrées utilisateur d'un formulaire

Lorsque nous devons gérer des formulaires côté front, il arrive souvent que nous ayons besoin de synchroniser l'état des éléments de saisi du formulaire avec l'état correspondant en JavaScript. Cela peut être encombrant de connecter les liaisons des valeurs et de changer les écouteurs d'événements :

template
<input
  :value="text"
  @input="event => text = event.target.value">

La directive v-model nous aide à simplifier le code ci-dessus par :

template
<input v-model="text">

De plus, v-model peut être utilisé sur des entrées de différents types, des éléments <textarea>, et <select>. Il s'étend automatiquement aux différentes paires de propriétés et d'événements du DOM en fonction de l'élément sur lequel il est utilisé :

  • Les éléments <input> de type texte et <textarea> utilisent la propriété value et l'événement input ;
  • <input type="checkbox"> et <input type="radio"> utilisent la propriété checked et l'événement change ;
  • <select> utilise value comme prop et change comme événement.

Remarque

v-model ignorera les attributs initiaux value, checked ou selected trouvés sur tout élément de formulaire. Il traitera toujours l'état actuel du JavaScript lié comme la source de vérité. Vous devez déclarer la valeur initiale côté JavaScript, à l'aide de l'option datades API de réactivité.

Utilisation basique

Texte

template
<p>Message is: {{ message }}</p>
<input v-model="message" placeholder="edit me" />

Message is:

Remarque

Pour les langages nécessitant un IME (chinois, japonais, coréen etc.), vous remarquerez que v-model n'est pas mis à jour pendant la composition de l'IME. Si vous souhaitez également réagir à ces mises à jour, utilisez votre propre écouteur d'événements input et votre propre liaison value au lieu d'utiliser v-model.

Texte multiligne

template
<span>Multiline message is:</span>
<p style="white-space: pre-line;">{{ message }}</p>
<textarea v-model="message" placeholder="add multiple lines"></textarea>
Multiline message is:

Notez que l'interpolation à l'intérieur de <textarea> ne fonctionnera pas. Utilisez v-model à la place.

template
<!-- À éviter -->
<textarea>{{ text }}</textarea>

<!-- OK -->
<textarea v-model="text"></textarea>

Checkbox

Case à cocher unique, valeur booléenne :

template
<input type="checkbox" id="checkbox" v-model="checked" />
<label for="checkbox">{{ checked }}</label>

Nous pouvons également lier plusieurs cases à cocher au même tableau ou à la même valeur Set :

js
const checkedNames = ref([])
js
export default {
  data() {
    return {
      checkedNames: []
    }
  }
}
template
<div>Checked names: {{ 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>
Checked names: []

Dans ce cas, le tableau checkedNames contiendra toujours les valeurs des cases qui sont actuellement cochées.

Radio

template
<div>Picked: {{ 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>
Picked:

Select

Simple select :

template
<div>Selected: {{ selected }}</div>

<select v-model="selected">
  <option disabled value="">Please select one</option>
  <option>A</option>
  <option>B</option>
  <option>C</option>
</select>
Selected:

Remarque

Si la valeur initiale de votre expression v-model ne correspond à aucune des options, l'élément <select> sera rendu dans un état "non sélectionné". Sous iOS, l'utilisateur ne pourra pas sélectionner le premier élément, car iOS ne déclenche pas d'événement de modification dans ce cas. Il est donc recommandé de fournir une option désactivée avec une valeur vide, comme le montre l'exemple ci-dessus.

Plusieurs select (liés à un tableau):

template
<div>Selected: {{ selected }}</div>

<select v-model="selected" multiple>
  <option>A</option>
  <option>B</option>
  <option>C</option>
</select>
Selected: []

Les options d'un select peuvent être rendues de manière dynamique avec 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" :value="option.value">
    {{ option.text }}
  </option>
</select>

<div>Selected: {{ selected }}</div>

Liaisons d'une valeur

Pour les options de type radio, checkbox et select, les valeurs de liaison du v-model sont généralement des chaînes de caractères statiques (ou des booléens pour les checkbox) :

template
<!-- `picked` est une chaîne de caractères valant "a" lorsqu'il est sélectionné -->
<input type="radio" v-model="picked" value="a" />

<!-- `toggle` peut être vrai ou faux -->
<input type="checkbox" v-model="toggle" />

<!-- `selected` est une chaîne de caractères valant "abc" lorsque la première option est sélectionnée -->
<select v-model="selected">
  <option value="abc">ABC</option>
</select>

Mais parfois, il peut arriver que nous voulions lier la valeur à une propriété dynamique sur l'instance actuellement active. Nous pouvons utiliser v-bind pour ce faire. De plus, l'utilisation de v-bind nous permet de lier la valeur d'entrée à des valeurs autres que des chaînes de caractères.

Checkbox

template
<input
  type="checkbox"
  v-model="toggle"
  true-value="yes"
  false-value="no" />

true-value et false-value sont des attributs spécifiques à Vue qui ne fonctionnent qu'avec v-model. Ici, la valeur de la propriété toggle sera définie à 'yes' lorsque la case est cochée, et à 'no' lorsqu'elle est décochée. Vous pouvez également les lier à des valeurs dynamiques en utilisant v-bind :

template
<input
  type="checkbox"
  v-model="toggle"
  :true-value="dynamicTrueValue"
  :false-value="dynamicFalseValue" />

Tip

Les attributs true-value et false-value n'affectent pas l'attribut value de l'entrée, car les navigateurs n'incluent pas les cases non cochées dans les soumissions de formulaires. Pour garantir qu'une des deux valeurs est soumise dans un formulaire (par exemple, "oui" ou "non"), utilisez plutôt des entrées de type radio.

Radio

template
<input type="radio" v-model="pick" :value="first" />
<input type="radio" v-model="pick" :value="second" />

pick prendra la valeur first lorsque la première entrée radio sera cochée, et prendra la valeur second lorsque la seconde sera cochée.

Options de select

template
<select v-model="selected">
  <!-- inline object literal -->
  <option :value="{ number: 123 }">123</option>
</select>

v-model supporte également les liaisons de valeurs autres que des chaînes de caractères ! Dans l'exemple précédent, lorsque l'option est sélectionnée, selected sera défini comme la valeur littérale de l'objet { number : 123 }.

Modificateurs

.lazy

Par défaut, v-model synchronise l'entrée avec les données après chaque événement input (à l'exception de la composition IME comme indiqué ci-dessus). Vous pouvez ajouter le modificateur lazy pour enclencher la synchronisation après les événements change :

template
<!-- synchronisé après "change" au lieu de "input" -->
<input v-model.lazy="msg" />

.number

Si vous voulez que l'entrée de l'utilisateur soit automatiquement typée comme un nombre, vous pouvez ajouter le modificateur number à vos entrées gérées par v-model :

template
<input v-model.number="age" />

Si la valeur ne peut pas être analysée avec parseFloat(), alors la valeur originale (chaîne) est utilisée à la place. En particulier, si l'entrée est vide (par exemple après que l'utilisateur ait effacé le champ de saisie), une chaîne vide est renvoyée. Ce comportement diffère de la propriété DOM valueAsNumber.

Le modificateur number est appliqué automatiquement si l'entrée possède type="number".

.trim

Si vous voulez que les espaces blancs des entrées utilisateur soient automatiquement supprimés, vous pouvez ajouter le modificateur trim à vos entrées gérées par v-model :

template
<input v-model.trim="msg" />

v-model avec les composants

Si vous n'êtes pas encore familiarisé avec les composants de Vue, vous pouvez sauter cette étape pour le moment.

Les types de saisie natifs dans HTML ne répondent pas toujours à vos besoins. Heureusement, les composants Vue vous permettent de construire des entrées réutilisables avec un comportement complètement personnalisé. Ces entrées fonctionnent même avec v-model ! Pour en savoir plus, lisez à propos de l'utilisation avec v-model dans le guide des composants.

Liaisons des entrées utilisateur d'un formulairea chargé