Cycle de vie et requêtes de données

Dans ce chapitre, vous apprendrez les hooks de cycle de vie de Vue3 et utiliserez fetch pour charger les données du blog à partir d'un fichier JSON au bon moment.


Qu'est-ce qu'un cycle de vie ?

Chaque composant Vue passe par une série d'étapes, de la création à la destruction ; ces étapes sont appelées le « cycle de vie ».

Vue fournit desfonctions de hookcorrespondantes à chaque étape, vous permettant d'exécuter du code à des moments précis.

Par exemple, si vous souhaitez récupérer des données après que le composant a fini de charger, vous devez utiliseronMountedce hook.


Aperçu des hooks de cycle de vie de Vue3

Fonction de hookMoment d'exécutionCas d'utilisation courants
setup()Initialisation du composant, s'exécute le plus tôtDéfinir les données réactives et les propriétés calculées
onBeforeMountAvant que le composant ne soit monté dans le DOMMoins couramment utilisé
onMountedAprès que le composant est monté dans le DOMEffectuer des requêtes réseau, initialiser des bibliothèques tierces, obtenir des références DOM
onBeforeUpdateAvant la modification des données et la mise à jour du DOMMoins couramment utilisé
onUpdatedAprès les changements de données et les mises à jour du DOMOpérations après les mises à jour du DOM
onBeforeUnmountAvant la destruction du composantNettoyer les timers, annuler les abonnements, supprimer les écouteurs d'événements
onUnmountedAprès la destruction du composantConfirmer le travail de nettoyage

Pour le projet de blog, celui que nous utilisons le plus souvent estonMounted—récupérer les données des articles après le chargement de la page.

Les hooks de cycle de vie doivent être écrits dans<script setup>setup, et ne peuvent pas être placés à l'intérieur de fonctions asynchrones ou d'instructions conditionnelles. Vue détermine à quel composant ils appartiennent en fonction de l'ordre des appels.


Utilisation de base de onMounted

Exemple

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

const message = ref('Chargement...')

// onMounted s'exécute après que le composant est monté sur la page
onMounted(() => {
// À ce stade, le DOM a terminé son rendu, il est donc sûr de manipuler le DOM ou d'envoyer des requêtes.
console.log('Le composant est monté, on peut maintenant commencer à charger les données')
message.value = 'Chargement des données terminé !'
})
</script>

<template>
  <p>{{ message }}</p>
</template>

Un composant peut appeler onMounted plusieurs fois, et ils s'exécuteront dans l'ordre d'enregistrement.


Chargement de données JSON avec fetch

Nous allons mettre les données de l'article dans un fichier JSON, puis utiliser fetch dans onMounted pour les charger.

Étape 1 : Créer un fichier de données

Exemple

// Chemin du fichier : public/posts.json
[
  {
    "id": 1,
"title": "Guide complet pour débutants Vue3",
"summary": "fromzerostart Apprenez l'API de composition Vue3, couvrant ref, reactive, computed et les concepts clés.",
"content": "<h2>Pourquoi apprendre Vue3 ?</h2><p>Vue3 est actuellement l'un des frameworks frontend les plus populaires...</p>",
    "category": "Vue",
    "date": "2024-05-10"
  },
  {
    "id": 2,
"title": "La programmation asynchrone en JavaScript expliquée"
"summary": "Un article pour comprendre Promise, async/await, la boucle d'événements et la file des microtâches.",
"content": "<h2>Qu’est-ce que l’asynchrone ?</h2><p>JS est monothread...</p>",
    "category": "JavaScript",
    "date": "2024-05-08"
  },
  {
    "id": 3,
"title": "CSS Grid Layout en action"
"summary": "Implémentez facilement des mises en page responsives complexes avec CSS Grid.",
"content": "<h2>Premiers pas avec Grid</h2><p>Grid est un système de mise en page bidimensionnel...</p>",
    "category": "CSS",
    "date": "2024-05-05"
  }
]

Le fichier JSON est placé dans lepublic/répertoire. Vite le servira directement comme fichier statique. Dans le navigateur, vous pouvez y accéder via/posts.jsondirectement. Les fichiers placés dans public ne sont pas compilés ; ils sont copiés tels quels dans la sortie de build.

Étape 2 : Récupérer les données dans le composant

Exemple

<!-- Chemin de fichier : src/views/HomeView.vue -->
<script setup>
import { ref, onMounted } from 'vue'
import BlogCard from '../components/BlogCard.vue'
import CategoryFilter from '../components/CategoryFilter.vue'

const articles = ref([]) // tableau vide initial
const isLoading = ref(true) // état de chargement
const error = ref(null) // message d'erreur

// Charger les données des articles de manière asynchrone
async function fetchPosts() {
  isLoading.value = true
  error.value = null
  try {
    const response = await fetch('/posts.json')
// Vérifier si la réponse est réussie (lève une erreur sur 404 ou 500)
    if (!response.ok) {
throw new Error(`Échec du chargement : HTTP ${response.status}`)
    }
    const data = await response.json()
    articles.value = data
  } catch (err) {
    error.value = err.message
console.error('Échec du chargement des données de l'article :', err)
  } finally {
    isLoading.value = false
  }
}

// Charger les données immédiatement après le montage du composant
onMounted(() => {
  fetchPosts()
})
</script>

<template>
  <div class="home">
    <h2>Derniers articles</h2>

    <!-- État de chargement -->
    <p v-if="isLoading" class="status-msg">Chargement, veuillez patienter...</p>

    <!-- État d'erreur -->
    <p v-else-if="error" class="status-msg error">
Échec du chargement : {{ error }}
      <button @click="fetchPosts">Réessayer</button>
    </p>

    <!-- État de données vide -->
    <p v-else-if="articles.length === 0" class="status-msg">
Pas encore d'articles, restez à l'écoute.
    </p>

    <!-- Affichage normal des données -->
    <template v-else>
      <div class="article-grid">
        <BlogCard
         v-for="article in articles"
         :key="article.id"
         :id="article.id"
         :title="article.title"
         :summary="article.summary"
         :date="article.date"
         :category="article.category"
       />
      </div>
    </template>
  </div>
</template>

<style scoped>
.status-msg {
  text-align: center;
  padding: 60px 0;
  font-size: 16px;
  color: #999;
}
.error { color: #e74c3c; }
.error button {
  margin-left: 10px;
  padding: 4px 12px;
  cursor: pointer;
}
</style>

Gestion des trois états des requêtes asynchrones

Chaque requête de données doit couvrir les trois états d'interface utilisateur suivants, sinon l'expérience utilisateur sera médiocre :

StateQuand il apparaîtReprésentation de l'interface utilisateur
ChargementAprès l'envoi de la requête, avant le retour de la réponseAnimation de chargement, écran squelette
SuccèsLes données sont renvoyées correctementAfficher le contenu normalement
FailureErreur réseau, exception serveurMessage d'erreur + bouton de nouvelle tentative

Vous pouvez également gérer un quatrième état—données vides(la requête réussit mais renvoie un tableau vide), en donnant aux utilisateurs un message clair au lieu d'une page blanche.


Mise en pratique : Basculez aussi la page de détail vers le chargement avec fetch

La page de détail doit trouver l'article correspondant dans le JSON en fonction de l'ID dans l'URL.

Vous pouvez réutiliser la logique de chargement des données—appelez aussi fetch sur la page de détail, puis filtrez.

Exemple

<!-- Chemin du fichier : src/views/PostView.vue -->
<script setup>
import { ref, computed, onMounted } from 'vue'
import { useRoute, RouterLink } from 'vue-router'

const route = useRoute()
const id = Number(route.params.id)

const posts = ref([]) // tous les articles
const isLoading = ref(true)
const error = ref(null)

// Trouver l'article courant par ID
const article = computed(() => {
  return posts.value.find(p => p.id === id)
})

// Charger toutes les données des articles
async function fetchPosts() {
  isLoading.value = true
  try {
    const res = await fetch('/posts.json')
if (!res.ok) throw new Error('Échec du chargement')
    posts.value = await res.json()
  } catch (err) {
    error.value = err.message
  } finally {
    isLoading.value = false
  }
}

onMounted(() => {
  fetchPosts()
})
</script>

<template>
  <div class="post-view">
    <p v-if="isLoading">Chargement...</p>
    <p v-else-if="error">Échec du chargement : {{ error }}</p>
    <div v-else-if="!article">
      <h2>L'article n'existe pas</h2>
      <RouterLink to="/">Retour à l'accueil</RouterLink>
    </div>
    <article v-else>
      <span class="category-tag">{{ article.category }}</span>
      <h1>{{ article.title }}</h1>
      <time>{{ article.date }}</time>
      <div class="content" v-html="article.content"></div>
      <RouterLink to="/">← Retour à l'accueil</RouterLink>
    </article>
  </div>
</template>

Résumé du chapitre

Dans ce chapitre, vous avez maîtrisé le hook de cycle de vie Vue3 le plus essentiel, onMounted, utilisé fetch pour charger des données JSON depuis le répertoire public, et appris à gérer les quatre états d’interface d’une requête (chargement/succès/échec/vide).

Maintenant, les données du blog sont chargées de manière asynchrone à partir d’un fichier JSON externe, ce qui se rapproche du fonctionnement des projets réels.

Autres extensions