Premiers pas avec Vue
Cours · Vue : construire une application web (école d'ingénieur), chapitre 1 · école d'ingénieur, informatique · le début du chapitre, la suite sur Adloun
À la fin du livre JavaScript, la Librairie du Campus savait filtrer son catalogue, remplir un panier, guider une commande. Chaque fonctionnalité reposait sur le même schéma : retrouver des éléments avec querySelector, écouter un événement, modifier une variable, puis penser à remettre à jour tous les endroits de la page qui en dépendent. Le compteur du panier dans l'en-tête, le total, le bouton désactivé, le message « Panier vide » : oublier un seul de ces endroits, et la page affiche une information fausse.
Vue propose une autre manière d'écrire une interface. On décrit, une fois pour toutes, ce que la page doit montrer en fonction des données ; quand les données changent, Vue met la page à jour, et seulement les parties concernées. Ce chapitre installe Vue dans une simple page HTML, présente l'application, le gabarit et la première donnée réactive, et refait avec Vue la fiche d'un livre de la Librairie.
Objectifs du chapitre
- Expliquer la différence entre une interface écrite de façon impérative (le DOM modifié à la main) et une interface déclarative.
- Charger Vue depuis un CDN, créer une application avec
createAppet la monter sur un élément. - Afficher des données dans un gabarit avec l'interpolation
{{ }}et connaître ses limites. - Déclarer une donnée réactive avec
refet observer la mise à jour automatique de la page. - Reconnaître l'API d'options, lire les avertissements de Vue dans la console, utiliser l'Atelier web et les outils de développement.
Les rendus et les affichages de console de ce chapitre ont été produits dans le navigateur Chromium, avec Vue 3.5.43, en simulant les clics décrits avec l'outil Playwright.
1.1 Pourquoi un framework ?
Commençons par un panier minuscule, écrit comme au livre JavaScript : un paragraphe qui indique le nombre d'articles et le total, un bouton pour ajouter un livre, un bouton pour vider le panier, désactivé quand le panier est vide.
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Panier, à la main</title>
<link rel="stylesheet" href="../exemple.css">
<script src="script.js" defer></script>
</head>
<body>
<p>Panier : <span id="nombre">0</span> article(s) — <span id="total">0,00 €</span></p>
<button type="button" id="ajouter">Ajouter « Programmation Java » (32 €)</button>
<button type="button" id="vider" disabled>Vider le panier</button>
</body>
</html>
const PRIX = 32;
let nombre = 0;
const champNombre = document.querySelector("#nombre");
const champTotal = document.querySelector("#total");
const ajouter = document.querySelector("#ajouter");
const vider = document.querySelector("#vider");
function euros(montant) {
return montant.toLocaleString("fr-FR", { style: "currency", currency: "EUR" });
}
// Après CHAQUE changement de nombre, il faut penser à tout remettre à jour.
function afficher() {
champNombre.textContent = String(nombre);
champTotal.textContent = euros(nombre * PRIX);
vider.disabled = nombre === 0;
}
ajouter.addEventListener("click", () => {
nombre += 1;
afficher();
});
vider.addEventListener("click", () => {
nombre = 0;
afficher();
});
Après deux clics sur « Ajouter », puis un clic sur « Vider », le paragraphe et l'état du bouton « Vider » (disabled) valent :
Panier : 2 article(s) — 64,00 €
false
Panier : 0 article(s) — 0,00 €
true
Le programme fonctionne, mais regardons sa structure. L'état de l'interface tient dans une seule variable, nombre. Tout le reste est de la plomberie : quatre références vers des éléments, une fonction afficher qui recopie l'état dans trois endroits de la page, et deux écouteurs qui n'oublient pas de l'appeler. Le code HTML de départ doit en plus être cohérent avec l'état initial (le « 0,00 € » et l'attribut disabled écrits à la main). Si demain l'en-tête affiche lui aussi le nombre d'articles, il faudra une cinquième référence et une ligne de plus dans afficher, et ne pas oublier les autres scripts qui modifient le panier.
Un code d'interface est impératif quand il décrit les opérations à faire sur la page (« mets ce texte dans cet élément, désactive ce bouton »). Il est déclaratif quand il décrit le résultat voulu en fonction de l'état (« ce paragraphe affiche le nombre d'articles ; ce bouton est désactivé quand le nombre vaut 0 ») et laisse un outil calculer les opérations.
Voici le même panier avec Vue. La page contient un gabarit : du HTML où des expressions entre doubles accolades et des attributs spéciaux disent ce qui dépend de l'état.
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Panier, avec Vue</title>
<link rel="stylesheet" href="../exemple.css">
<script src="https://unpkg.com/vue@3.5.43/dist/vue.global.js"></script>
<script src="app.js" defer></script>
</head>
<body>
<div id="app">
<p>Panier : {{ nombre }} article(s) — {{ euros(nombre * PRIX) }}</p>
<button type="button" @click="nombre++">Ajouter « Programmation Java » (32 €)</button>
<button type="button" :disabled="nombre === 0" @click="nombre = 0">Vider le panier</button>
</div>
</body>
</html>
const { createApp, ref } = Vue;
const PRIX = 32;
function euros(montant) {
return montant.toLocaleString("fr-FR", { style: "currency", currency: "EUR" });
}
createApp({
setup() {
const nombre = ref(0);
return { nombre, PRIX, euros };
},
}).mount("#app");
Le rendu après trois clics sur « Ajouter » :

Le paragraphe, au chargement puis après les trois clics :
Panier : 0 article(s) — 0,00 €
Panier : 3 article(s) — 96,00 €
et après un ajout puis un clic sur « Vider » (le paragraphe, puis l'état disabled du bouton « Vider ») :
Panier : 0 article(s) — 0,00 €
true
Il n'y a plus ni querySelector, ni addEventListener, ni fonction afficher. Le gabarit dit une fois que le paragraphe montre {{ nombre }} et le total, que le bouton « Vider » est désactivé quand nombre === 0, et ce que font les clics. Quand nombre change, Vue recalcule ce qui en dépend et modifie le DOM pour nous. Les deux syntaxes nouvelles du gabarit, @click (écouter un événement) et :disabled (lier un attribut à une expression), sont détaillées au chapitre 2 ; ce chapitre se concentre sur l'application, l'interpolation et la donnée réactive.
Avec Vue, on écrit l'interface comme une fonction de l'état : le gabarit décrit la page pour n'importe quelle valeur des données. On ne modifie plus la page ; on modifie les données, et Vue rend la page à nouveau.
Un framework comme Vue (ou React, Angular, Svelte) apporte d'abord cette mise à jour automatique, mais aussi une façon de découper une interface en composants réutilisables (chapitre 5), des outils pour les applications de plusieurs écrans (routeur, chapitre 9) et un état partagé (chapitre 10). Il a un coût : une bibliothèque à charger (168 Ko pour la version de production utilisée ici, 61 Ko une fois compressée pour le transfert), des règles à apprendre. Pour une page avec un seul bouton, le JavaScript écrit à la main reste plus simple ; dès que plusieurs endroits de la page dépendent des mêmes données, le framework devient rentable.
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 coursEn accès libre, sans inscription.