Skip to content

Les bases de Vue.js

Cette page présente les concepts de base de Vue.js, en se concentrant sur la Composition API, sous une forme de cheat sheet, afin de vous aider à démarrer rapidement ou vous rappeler les fondamentaux.

💡 Pour les débutants

Si c'est votre première fois avec un framework JavaScript comme Vue.js, je vous conseille de réaliser le tutoriel officiel Vue.js pour bien comprendre les concepts de base.

1. Rendu déclaratif

📘 Documentation

🎯 Objectif

Afficher du contenu HTML à partir de variables JavaScript, sans manipuler le DOM manuellement. Vue se charge de tout mettre à jour automatiquement quand les données changent.

💡 Utilité

Permet d’écrire du HTML dynamique, lisible et maintenable. Vue relie directement le modèle (data) et la vue (template).

💻 Exemple

vue
<template>
  <!-- Le contenu entre s'actualise automatiquement -->
  <h2>Bonjour {{ prenom }} !</h2>
</template>

<script setup>
  // Importation de la fonction ref qui crée des données réactives
  import {ref} from 'vue'

  // Une donnée réactive (modèle)
  const prenom = ref('Sacha')
</script>
  • ref('Sacha') crée une référence réactive : une sorte de "boîte" contenant la valeur "Sacha".
  • Dans <template>, Vue accède directement à la valeur contenue dans la boîte.
  • Dans <script>, il faut utiliser .value pour accéder ou modifier la valeur contenue dans la boîte.
js
// Modifier la valeur de la référence réactive prenom
prenom.value = 'Ondine' // Met à jour l'affichage dans le template

✅ Bonnes pratiques

  • Toujours nommer les variables de manière claire (prenom, email, etc.)
  • Ne pas effectuer de logique complexe dans les accolades {{ variable }}
  • Limiter l’utilisation des interpolations à l’essentiel (éviter des doubles appels ou des expressions longues)

2. Liaisons d’attributs (v-bind)

📘 Documentation

🎯 Objectif

Lier une donnée JavaScript à un attribut HTML ou une propriété de composant (comme src, alt, href, color, etc.).

Pour rendre un attribut dynamique, on utilise v-bind ou sa version abrégée :.

  • v-bind:src:src
  • v-bind:alt:alt

💡 Utilité

Permet de rendre les composants plus dynamiques : images, classes CSS, valeurs numériques, etc.

💻 Exemple

vue
<template>
  <!-- L’attribut src est lié dynamiquement à imageUrl -->
  <img :src="imageUrl" :alt="description"/>
</template>

<script setup>
  // Importation de ref pour créer des données réactives
  import {ref} from 'vue'

  const imageUrl = ref('/images/pikachu.png')
  const description = ref('Image de Pikachu')
</script>
  • :src="..." est une liaison dynamique : la valeur de l’attribut src changera si imageUrl change.
  • :alt fonctionne de la même façon.

✅ Bonnes pratiques

  • Utiliser :class et :style pour gérer dynamiquement l’apparence
  • Toujours utiliser ref pour lier une valeur qui peut changer
  • Préférer la syntaxe abrégée :attr à v-bind:attr pour plus de lisibilité

3. Gestion des événements (@click, @input, etc.)

📘 Documentation

🎯 Objectif

Réagir à une action de l'utilisateur (clic, saisie, soumission, etc.).

💡 Utilité

Permet d’ajouter de l’interactivité à votre application (boutons, formulaires, actions dynamiques).

💻 Exemple

vue
<template>
  <!-- Quand on clique sur le bouton, on exécute la fonction incrementer -->
  <v-btn @click="incrementer">Cliquez ({{ compteur }})</v-btn>
</template>

<script setup>
  // Importation de ref pour créer un compteur réactif
  import {ref} from 'vue'

  const compteur = ref(0)

  // Fonction appelée au clic sur le bouton
  function incrementer() {
    compteur.value++ // On met à jour la valeur avec .value
  }
</script>
  • Les événements s’écrivent avec le symbole @, comme @click, @input, @submit...
  • Chaque événement appelle une fonction JS définie dans <script setup>.
  • Comme compteur est une référence (ref), on doit utiliser .value pour l’incrémenter.

Exemples d’événements

@click     → quand un élément est cliqué
@dblclick  → quand un élément est double-cliqué
@submit    → quand un formulaire est envoyé
@input     → lorsqu’un utilisateur tape dans un champ texte
@change    → quand la valeur d’un champ change
@mouseover → quand la souris passe sur un élément
@keyup     → quand une touche est relâchée
@keydown   → quand une touche est enfoncée
@focus     → quand un champ texte reçoit le focus
@blur      → quand un champ texte perd le focus

La liste complète des événements :https://www.w3schools.com/jsref/dom_obj_event.asp

Les modificateurs d’événements

.stop      → arrête la propagation de l’événement
.prevent   → empêche le comportement par défaut
.self      → ne déclenche l’événement que si l’élément lui-même est cliqué
.capture   → écoute l’événement avant les enfants
.once      → n’exécute l’événement qu’une seule fois
.passive   → indique que l’événement ne va pas appeler preventDefault

💻 Exemple

vue

<!-- la propagation de l'événement clic va être arrêtée -->
<a @click.stop="doThis"></a>

<!-- l'événement submit ne va plus rafraîchir la page -->
<form @submit.prevent="onSubmit"></form>

<!-- les modificateurs peuvent être chaînés -->
<a @click.stop.prevent="doThat"></a>

<!-- seulement le modificateur -->
<form @submit.prevent></form>

<!-- ne déclenche le gestionnaire que si event.target est l'élément lui-même. -->
<!-- par exemple pas depuis un élément enfant -->
<div @click.self="doThat">...</div>

Modificateurs de touche

Il est possible d’ajouter des modificateurs de touche pour les événements clavier. Par exemple, pour exécuter une fonction uniquement lorsque la touche enter est enfoncée :

vue
<!-- appelle `submit` seulement lorsque `key` est `Enter` -->
<input @keyup.enter="submit" />

Alias de touche

.enter
.tab
.delete   → capture à la fois les touches "Delete" et "Backspace"
.esc
.space
.up
.down
.left
.right

Touches de modification du système

On peut combiner les touches de modification du système avec d’autres événements clavier. Par exemple, pour exécuter une fonction uniquement lorsque la touche ctrl est enfoncée :

vue
<!-- Alt + Entrée -->
<input @keyup.alt.enter="clear" />

<!-- Ctrl + Clic -->
<div @click.ctrl="doSomething">Do something</div>
Alias de touche de modification
.ctrl
.alt
.shift
.meta     → touche "Windows" ou "Command" sur Mac

✅ Bonnes pratiques

  • Toujours nommer vos fonctions de manière claire (incrementer, soumettreFormulaire, etc.)
  • Ne jamais inclure de logique métier directement dans l’attribut @click="..."
  • Ne pas oublier .prevent, .stop si nécessaire (ex: @submit.prevent)

4. Liaison sur les champs de formulaire (v-model)

📘 Documentation

🎯 Objectif

Relier un champ de formulaire à une donnée réactive avec la directive v-model.

💡 Utilité

Permet de synchroniser automatiquement les valeurs saisies par l’utilisateur avec les données de l’application.

💻 Exemple

vue
<template>
  <!-- Liaison bidirectionnelle : saisie utilisateur = valeur JS -->
  <v-text-field v-model="nom" label="Votre nom" />
  <p>Bonjour, {{ nom }} !</p>
</template>

<script setup>
  import { ref } from 'vue'
  const nom = ref('')
</script>
  • v-model crée un lien entre l’interface et la donnée : chaque modification met à jour nom.value.
  • Dans <template>, l’affichage se met à jour automatiquement.

✅ Bonnes pratiques

  • Initialiser les champs avec une valeur par défaut logique (chaîne vide, null, etc.)
  • Préférer des noms clairs : email, motDePasse, etc.

5. Rendu conditionnel (v-if, v-else, v-show)

📘 Documentation

🎯 Objectif

Afficher ou masquer dynamiquement des éléments dans le DOM avec les directives v-if, v-else et v-else-if ou v-show.

💡 Utilité

Utile pour afficher un contenu seulement si une certaine condition est vraie (authentification, validation, rupture de stock, etc.).

💻 Exemple

vue
<template>
  <p v-if="connecte">Bienvenue !</p>
  <p v-else>Veuillez vous connecter.</p>
  
  <button v-show="connecte">Se déconnecter</button>
</template>

<script setup>
  import { ref } from 'vue'
  const connecte = ref(false)
</script>
  • v-if et v-else insère ou retire l’élément du DOM.
  • v-show garde l’élément dans le DOM, mais le cache avec display: none.

✅ Bonnes pratiques

  • Utiliser v-if pour des conditions critiques (connexion, données disponibles).
  • Préférer v-show pour les éléments fréquemment affichés/masqués (ex: menu).
  • Éviter les chaînes de v-else-if trop longues.

6. Rendu de liste (v-for)

📘 Documentation

🎯 Objectif

Afficher une collection d’éléments HTML à partir d’un tableau JavaScript avec la directive v-for.

💡 Utilité

Permet d’afficher dynamiquement une liste de données dans une boucle.

💻 Exemple

vue
<template>
  <ul>
    <!-- Boucle sur chaque Pokémon -->
    <li v-for="pokemon in pokemons" :key="pokemon.id">
      {{ pokemon.name }}
    </li>
  </ul>
</template>

<script setup>
  import { ref } from 'vue'
  const pokemons = ref([
    { id: 1, name: 'Pikachu' },
    { id: 2, name: 'Salamèche' },
    { id: 3, name: 'Carapuce' }
  ])
</script>
  • Toujours utiliser :key avec une valeur unique (id) pour chaque élément.
  • Cela permet à Vue de mieux gérer le DOM virtuel.

✅ Bonnes pratiques

  • Ne pas oublier le :key unique pour chaque itération
  • Éviter de modifier directement le tableau (préférer une copie)
  • Afficher un message s’il n’y a aucun élément (v-if="pokemons.length === 0")

7. Propriétés calculées (computed)

📘 Documentation

🎯 Objectif

Créer une valeur dérivée d’autres données, automatiquement mise à jour quand les dépendances changent.

💡 Utilité

Idéal pour formater des données ou calculer une valeur sans créer une méthode explicite.

💡 Différence entre computed et methods

Dans une computed, La valeur est mémorisée et ne se recalculera que si ses dépendances changent.

À l'inverse, une méthode sera recalculée à chaque modification de l’interface.

Les computed sont donc plus performantes pour des calculs lourds ou répétitifs.

💻 Exemple

vue
<template>
  <p>Nom complet : {{ nomComplet }}</p>
</template>

<script setup>
  import {ref, computed} from 'vue'

  const prenom = ref('Sacha')
  const nom = ref('Ketchum')

  const nomComplet = computed(() => `${prenom.value} ${nom.value}`)
</script>
  • computed() retourne une référence qui dépend d’autres valeurs.
  • Le résultat est mis à jour automatiquement dès qu’une dépendance change.

✅ Bonnes pratiques

  • Utiliser computed pour toute donnée dérivée d’un ref ou reactive.
  • Ne pas effectuer de logique async dans computed (utiliser un watch dans ce cas).

8. Cycle de vie et refs de template

📘 Documentation

🎯 Objectif

Réagir à différentes étapes de la vie d’un composant (montage, mise à jour, destruction).

💡 Utilité

Permet d’exécuter du code au bon moment (chargement de données, initialisation, focus...).

L'événement mounted est le plus utilisé pour exécuter du code après le montage du composant. C'est à ce moment que l'on peut accéder aux éléments du DOM et effectuer des appels API pour récupérer des données.

♻️ Cycle de vie d'un composant

lifecycle.png

💻 Exemple

vue
<template>
  <input ref="champ" placeholder="Clic auto au démarrage"/>
</template>

<script setup>
  import {ref, onMounted} from 'vue'

  const champ = ref(null)

  onMounted(() => {
    champ.value.focus() // Donne le focus à l'input au chargement
  })
</script>

Toutes les étapes du cycle de vie

Tous les cycles de vie sont disponibles dans Vue 3, mais certains ne sont pas utilisables dans <script setup> avec la Composition API.

Ci-dessous, un exemple complet avec tous les hooks du cycle de vie compatibles.

vue
<template>
  <!-- Bouton qui modifie une donnée réactive pour déclencher un cycle de mise à jour -->
  <button @click="increment">Compteur : {{ count }}</button>
</template>

<script setup>
  // Importation des hooks du cycle de vie nécessaires
  import {
    ref,
    onBeforeMount,
    onMounted,
    onBeforeUpdate,
    onUpdated,
    onBeforeUnmount,
    onUnmounted,
    onErrorCaptured
  } from 'vue'

  // Donnée réactive pour provoquer des mises à jour
  const count = ref(0)

  // ✅ Avant que le composant ne soit monté dans le DOM
  onBeforeMount(() => {
    console.log('→ before mount')
  })

  // ✅ Une fois le composant monté dans le DOM
  onMounted(() => {
    console.log('→ mounted')
  })

  // ⚠️ Appelé juste avant une mise à jour du DOM (si une donnée réactive change)
  onBeforeUpdate(() => {
    console.log('→ before update')
  })

  // ⚠️ Appelé juste après une mise à jour du DOM (suite à un changement réactif)
  onUpdated(() => {
    console.log('→ updated')
  })

  // ✅ Avant que le composant ne soit démonté
  onBeforeUnmount(() => {
    console.log('→ before unmount')
  })

  // ✅ Après que le composant soit démonté
  onUnmounted(() => {
    console.log('→ unmounted')
  })

  // ✅ Capture des erreurs dans les composants enfants
  onErrorCaptured((err, instance, info) => {
    console.error('→ erreur capturée :', err)
    return false // retourne true pour stopper la propagation
  })

  // Fonction pour incrémenter le compteur
  function increment() {
    count.value++
  }
</script>
  • ref(null) est utilisé pour cibler un élément HTML via ref="champ".
  • onMounted() s’exécute une seule fois après le rendu initial du composant.

✅ Bonnes pratiques

  • Utiliser onMounted pour les opérations DOM ou les appels API initiaux.
  • Toujours tester si .value existe avant d’y accéder (if (champ.value)).

9. Observateurs (watch)

📘 Documentation

🎯 Objectif

Surveiller un changement de valeur et exécuter une action spécifique.

💡 Utilité

Indispensable quand on veut déclencher une logique métier suite à une modification de donnée.

💻 Exemple

vue
<template>
  <p>Compteur : {{ compteur }}</p>
  <button @click="compteur++">Incrémenter</button>
</template>

<script setup>
  import {ref, watch} from 'vue'

  const compteur = ref(0)

  watch(compteur, (nouvelleValeur, ancienneValeur) => {
    console.log(`Compteur changé de ${ancienneValeur} à ${nouvelleValeur}`)
  })
</script>
  • watch() prend comme premier argument une valeur à observer (ici compteur).
  • La fonction est appelée à chaque changement de la valeur observée (ici compteur).

✅ Bonnes pratiques

  • Utiliser watch pour exécuter des effets secondaires (API, DOM, logs...)
  • Préférer computed si vous ne faites que retourner une valeur.