Component Architecture
Thème :
Junior
1 vues ·10/11 leçonsGérer l’Asynchrone avec Suspense
<Suspense> est un composant intégré qui gère les dépendances asynchrones dans l’arbre de composants, en affichant un contenu de repli pendant l’attente.
Utilisation de Base de Suspense
<template>
<Suspense>
<!-- Composant avec un setup asynchrone -->
<template #default>
<AsyncComponent />
</template>
<!-- Affiché pendant le chargement -->
<template #fallback>
<LoadingSpinner />
</template>
</Suspense>
</template>
Setup Asynchrone dans les Composants
Les composants avec des opérations asynchrones dans <script setup> déclenchent Suspense :
<!-- UserProfile.vue -->
<script setup lang="ts">
// L'await de premier niveau rend ce composant asynchrone
const response = await fetch('/api/user');
const user = await response.json();
</script>
<template>
<div class="profile">
<h1>{{ user.name }}</h1>
<p>{{ user.email }}</p>
</div>
</template>
<!-- Parent -->
<template>
<Suspense>
<UserProfile />
<template #fallback>
<p>Chargement du profil...</p>
</template>
</Suspense>
</template>
Dépendances Asynchrones Multiples
Suspense attend que TOUTES les dépendances asynchrones soient résolues :
<template>
<Suspense>
<template #default>
<div class="dashboard">
<UserStats />
<!-- asynchrone -->
<RecentActivity />
<!-- asynchrone -->
<Notifications />
<!-- asynchrone -->
</div>
</template>
<template #fallback>
<DashboardSkeleton />
</template>
</Suspense>
</template>
Gestion des Erreurs avec onErrorCaptured
<script setup lang="ts">
import { ref, onErrorCaptured } from 'vue';
const error = ref<Error | null>(null);
onErrorCaptured((err) => {
error.value = err;
return false; // Empêcher la propagation
});
</script>
<template>
<div v-if="error" class="error">
<p>Une erreur est survenue : {{ error.message }}</p>
<button @click="error = null">Réessayer</button>
</div>
<Suspense v-else>
<AsyncContent />
<template #fallback>
<LoadingSpinner />
</template>
</Suspense>
</template>
Événements de Suspense
Écoutez les changements d’état de Suspense :
<script setup>
function onPending() {
console.log('Chargement démarré');
}
function onResolve() {
console.log('Chargement terminé');
}
function onFallback() {
console.log('Le repli est maintenant affiché');
}
</script>
<template>
<Suspense @pending="onPending" @resolve="onResolve" @fallback="onFallback">
<AsyncComponent />
<template #fallback>
<Loading />
</template>
</Suspense>
</template>
Suspense Imbriqué
Gérez différents états de chargement de façon indépendante :
<template>
<!-- Suspense externe pour la mise en page -->
<Suspense>
<template #default>
<AsyncLayout>
<!-- Suspense interne pour le contenu -->
<Suspense>
<template #default>
<AsyncContent />
</template>
<template #fallback>
<ContentSkeleton />
</template>
</Suspense>
</AsyncLayout>
</template>
<template #fallback>
<FullPageLoader />
</template>
</Suspense>
</template>
Exemple Pratique : Page de Récupération de Données
<!-- PostPage.vue -->
<script setup lang="ts">
import { ref, onErrorCaptured, Suspense } from 'vue';
const error = ref<Error | null>(null);
const key = ref(0);
onErrorCaptured((err) => {
error.value = err;
return false;
});
function retry() {
error.value = null;
key.value++; // Forcer le re-montage
}
</script>
<template>
<div class="post-page">
<div v-if="error" class="error-state">
<h2>Échec du chargement</h2>
<p>{{ error.message }}</p>
<button @click="retry">Réessayer</button>
</div>
<Suspense v-else :key="key">
<template #default>
<PostContent />
<CommentSection />
<RelatedPosts />
</template>
<template #fallback>
<div class="loading-state">
<PostSkeleton />
<CommentsSkeleton />
</div>
</template>
</Suspense>
</div>
</template>
<!-- PostContent.vue -->
<script setup lang="ts">
const props = defineProps<{ postId: string }>();
// Cet await déclenche Suspense dans le parent
const response = await fetch(`/api/posts/${props.postId}`);
if (!response.ok) throw new Error("Impossible de charger l'article");
const post = await response.json();
</script>
<template>
<article>
<h1>{{ post.title }}</h1>
<div v-html="post.content"></div>
</article>
</template>
Notes Importantes
- Fonctionnalité Expérimentale : Suspense est encore expérimental dans Vue 3
- Support SSR : Fonctionne avec le rendu côté serveur
- Keep-Alive : Compatible avec
<KeepAlive>pour la mise en cache - Transition : Le contenu Suspense peut être enveloppé avec
<Transition>
Ressources
- Suspense — Documentation officielle Vue sur Suspense
📘 Cette leçon fait partie du cours Architecture des Composants Vue sur Stanza — la plateforme d’apprentissage native à l’IDE pour les développeurs.
Prêt à passer à la suite ?
Vous avez terminé cette leçon sur Gérer l'Asynchrone avec Suspense. Continuez votre apprentissage avec la prochaine leçon ou explorez d'autres formations.