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énementinput
; <input type="checkbox">
et<input type="radio">
utilisent la propriétéchecked
et l'événementchange
;<select>
utilisevalue
comme prop etchange
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 des 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([])
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' }
])
template
<select v-model="selected">
<option v-for="option in options" :key="option.value" :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 est utilisée à la place.
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.