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 hook | Moment d'exécution | Cas d'utilisation courants |
|---|---|---|
| setup() | Initialisation du composant, s'exécute le plus tôt | Définir les données réactives et les propriétés calculées |
| onBeforeMount | Avant que le composant ne soit monté dans le DOM | Moins couramment utilisé |
| onMounted | Après que le composant est monté dans le DOM | Effectuer des requêtes réseau, initialiser des bibliothèques tierces, obtenir des références DOM |
| onBeforeUpdate | Avant la modification des données et la mise à jour du DOM | Moins couramment utilisé |
| onUpdated | Après les changements de données et les mises à jour du DOM | Opérations après les mises à jour du DOM |
| onBeforeUnmount | Avant la destruction du composant | Nettoyer les timers, annuler les abonnements, supprimer les écouteurs d'événements |
| onUnmounted | Après la destruction du composant | Confirmer 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
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
[
{
"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 le
public/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
<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 :
| State | Quand il apparaît | Représentation de l'interface utilisateur |
|---|---|---|
| Chargement | Après l'envoi de la requête, avant le retour de la réponse | Animation de chargement, écran squelette |
| Succès | Les données sont renvoyées correctement | Afficher le contenu normalement |
| Failure | Erreur réseau, exception serveur | Message 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
<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