Adloun

Formulaires

Cours · Vue : construire une application web (école d'ingénieur), chapitre 4 · école d'ingénieur, informatique · le début du chapitre, la suite sur Adloun

Jusqu'ici, les données allaient du script vers la page. Un formulaire fait le chemin inverse : le visiteur tape un nom, coche des rayons, choisit un livre, et l'application doit le savoir pendant la saisie, pour calculer un total, signaler une erreur, activer un bouton. Au livre JavaScript, le formulaire de commande de la Librairie lisait les champs à chaque événement input et réécrivait les messages à la main. Vue relie un champ à une donnée dans les deux sens avec une seule directive, v-model ; la validation devient une propriété calculée.

Objectifs du chapitre

  • Relier un champ à une donnée avec v-model, et savoir ce que la directive fait à la place du programmeur.
  • Connaître la valeur produite par chaque type de champ : texte, case à cocher seule ou multiple, boutons radio, listes simples et multiples.
  • Utiliser les modificateurs .trim, .number et .lazy.
  • Valider un formulaire : messages calculés, affichés au bon moment, reliés au champ pour un lecteur d'écran, focus sur la première erreur.
  • Réécrire le formulaire de commande de la Librairie.

Les valeurs montrées dans ce chapitre ont été relevées dans Chromium, avec Vue 3.5.43, en simulant les saisies décrites (frappes, cases cochées, choix dans les listes) avec l'outil Playwright.

4.1 v-model


<div id="app">
  <p><label>Votre prénom <input type="text" v-model="prenom"></label></p>
  <p><label>Le même, à la main <input type="text" :value="prenom" @input="prenom = $event.target.value"></label></p>
  <p>Bonjour {{ prenom || "inconnu" }} !</p>
  <button type="button" @click="prenom = 'Awa'">Pré-remplir « Awa »</button>
</div>

const { createApp, ref } = Vue;

createApp({
  setup() {
    const prenom = ref("");
    return { prenom };
  },
}).mount("#app");

On tape « Léa » dans le premier champ : le paragraphe, puis la valeur des deux champs. On clique ensuite sur le bouton, et l'on relève les mêmes informations :


Bonjour Léa !
"Léa" "Léa"
Bonjour Awa !
"Awa" "Awa"
Définition 4.1Liaison bidirectionnelle

v-model="donnee" relie un champ de formulaire à une donnée réactive dans les deux sens : la saisie modifie la donnée, et une modification de la donnée (par le script) modifie le champ. Sur un champ de texte, c'est l'abrégé de :value="donnee" plus @input="donnee = …", comme l'écrit le deuxième champ.

La donnée est la seule source de vérité : la valeur initiale du champ est celle de la donnée (un attribut value écrit dans le gabarit serait ignoré), et un bouton « Pré-remplir » n'a qu'à modifier la donnée. Les deux champs, reliés à la même ref, restent toujours identiques.

4.2 Chaque type de champ

La valeur que v-model lit et écrit dépend du champ. Le formulaire suivant les réunit tous ; ses données sont groupées dans un seul objet reactive, et la balise <pre> les affiche au format JSON.


<div id="app">
  <form @submit.prevent>
    <p><label>Avis <textarea v-model="f.avis" rows="2"></textarea></label></p>
    <p><label><input v-model="f.lettre" type="checkbox"> Recevoir la lettre</label></p>
    <fieldset>
      <legend>Rayons préférés</legend>
      <label v-for="r in rayons" :key="r"><input v-model="f.rayons" type="checkbox" :value="r"> {{ r }}</label>
    </fieldset>
    <fieldset>
      <legend>Retrait</legend>
      <label><input v-model="f.retrait" type="radio" value="boutique"> En boutique</label>
      <label><input v-model="f.retrait" type="radio" value="campus"> Livraison campus</label>
    </fieldset>
    <p>
      <label>Format
        <select v-model="f.format">
          <option disabled value="">— choisir —</option>
          <option value="broche">Broché</option>
          <option value="poche">Poche</option>
        </select>
      </label>
    </p>
    <p>
      <label>Langues
        <select v-model="f.langues" multiple>
          <option>Français</option>
          <option>Anglais</option>
          <option>Arabe</option>
        </select>
      </label>
    </p>
    <button type="submit">Enregistrer</button>
    <pre>{{ f }}</pre>
  </form>
</div>

const { createApp, reactive } = Vue;

createApp({
  setup() {
    const rayons = ["Informatique", "Mathématiques", "Littérature"];
    // Un objet réactif pour l'ensemble du formulaire.
    const f = reactive({
      avis: "",
      lettre: false,
      rayons: [],
      retrait: "boutique",
      format: "",
      langues: [],
    });
    return { rayons, f };
  },
}).mount("#app");

Au chargement, puis après avoir tapé un avis, coché « Recevoir la lettre », coché « Littérature » puis « Informatique », choisi la livraison sur le campus, le format « Poche », puis « Français » et « Arabe » dans la liste multiple :


{
  "avis": "",
  "lettre": false,
  "rayons": [],
  "retrait": "boutique",
  "format": "",
  "langues": []
}
--- après la saisie
{
  "avis": "Très clair",
  "lettre": true,
  "rayons": [
    "Littérature",
    "Informatique"
  ],
  "retrait": "campus",
  "format": "poche",
  "langues": [
    "Français",
    "Arabe"
  ]
}

Illustration

Proposition 4.2Valeur produite par v-model
  • Champ de texte, <textarea> : une chaîne.
  • Case à cocher reliée à un booléen : true ou false (ou les valeurs données par true-value et false-value).
  • Plusieurs cases reliées au même tableau : le tableau des value des cases cochées, dans l'ordre où elles ont été cochées (« Littérature » avant « Informatique »).
  • Boutons radio : la value du bouton choisi ; la donnée initiale coche le bouton correspondant.
  • <select> : la value de l'option choisie ; avec multiple, un tableau, dans l'ordre des options. Une option disabled value="" sert d'invite quand la donnée vaut "".

La suite du cours est sur Adloun

Le chapitre en entier, formules et figures comprises, avec le tuteur, les fiches, les QCM et les exercices.

Lire la suite du cours

En accès libre, sans inscription.

Exercices corrigés de ce chapitre

Lire la suite du cours →