Récupération de la data
Dans Nuxt, nous avons 2 façons de récupérer de la data depuis une API. Nous pouvons utiliser la méthode fetch ou bien asyncData.
Nuxt prend en charge les modèles Vue traditionnels pour le chargement de données dans votre application côté client, comme la récupération de données dans le hook mounted()
d'un composant. Cependant, les applications universelles doivent utiliser des hooks spécifiques à Nuxt pour pouvoir restituer les données lors du rendu côté serveur. Cela permet à votre page de s'afficher avec toutes ses données requises présentes.
Nuxt a deux hooks pour le chargement asynchrone des données:
-
Le hook
fetch
(Nuxt 2.12+). Ce hook peut être placé sur n'importe quel composant et fournit des raccourcis pour le rendu des états de chargement (pendant le rendu côté client) et des erreurs. -
Le hook
asyncData
. Ce hook ne peut être placé que sur les composants page. Contrairement àfetch
, ce hook n'affiche pas d'espace réservé de chargement pendant le rendu côté client: à la place, ce hook bloque la navigation de l'itinéraire jusqu'à ce qu'il soit résolu, affichant une erreur de page en cas d'échec.
fetch
fonctionnait un peu comme asyncData
aujourd'hui. Cette fonctionnalité est toujours supportée aujourd'hui pour des raisons de rétrocompatibilité: si un argument context
est accepté dans votre fetch()
, il sera considéré comme un hook de récupération "hérité". Cette fonctionnalité est obsolète et doit être remplacée par asyncData(context)
ou par un middleware anonyme en utilisant middleware(context)
.Ces hooks peuvent être utilisés avec toute bibliothèque de récupération de données que vous choisissez. Nous vous recommandons d'utiliser @nuxt/http ou @nuxt/axios pour faire des requêtes HTTP aux API. Vous trouverez plus d'informations sur ces bibliothèques, telles que des guides de configuration, des en-têtes d'authentification, dans leur documentation respective.
Le hook fetch
2.12+
.Le hook fetch
de Nuxt est appelé après que l'instanciation du composant soit faite côté serveur: this
est disponible à l'intérieur.
export default {
async fetch() {
console.log(this)
}
}
fetch(context)
a été déprécié dans nos pages, il faut utiliser un middleware anonyme à la place: middleware(context)
Quand utiliser fetch?
À chaque fois que nous avons besoin d'avoir de la data asynchrone. fetch
est appelé côté serveur lors du render de la route et côté client lors de la navigation.
Cela expose $fetchState
au niveau du composant et avec les propriétés suivantes:
-
pending
est un Booléen, il permet d'afficher un placeholder quandfetch
est appelé côté client. -
error
, il peut être soit ànull
soit àError
et nous permet d'afficher un message -
timestamp
est l'horodatage du dernierfetch
, cela peut s'avérer utile pour faire du cache aveckeep-alive
Nous avons aussi accès à this.$fetch()
, utile si nous voulons appeler le hook fetch
dans notre composant.
<template>
<p v-if="$fetchState.pending">Récupération des montagnes... ⛰️</p>
<p v-else-if="$fetchState.error">Une erreur est survenue :(</p>
<div v-else>
<h1>Montagnes Nuxt</h1>
<ul v-for="mountain of mountains">
<li>{{ mountain.title }}</li>
</ul>
<button @click="$fetch">Actualiser</button>
</div>
</template>
<script>
export default {
data() {
return {
mountains: []
}
},
async fetch() {
this.mountains = await fetch(
'https://api.nuxtjs.dev/mountains'
).then(res => res.json())
}
}
</script>
Options
fetchOnServer
: Un booléen ou une fonction (par défaut: true
), utile si on veut appeler fetch()
lors du render de la page côté serveur.
fetchDelay
: Un entier (par défaut: 200
), définit une limite minimale exprimée en millisecondes de temps d'exécution (pour éviter les flashs).
Lorsque fetchOnServer
est falsy (false
ou retourne quelque chose de faux), fetch
sera appelé uniquement côté client et $fetchState.pending
retournera true
lors du render du composant côté serveur.
export default {
data() {
return {
posts: []
}
},
async fetch() {
this.posts = await fetch('https://api.nuxtjs.dev/posts').then(res =>
res.json()
)
},
// on appelle fetch uniquement du côté client
fetchOnServer: false
}
Écoute des modifications des query strings
Le hook fetch
n'est pas appelé sur les modifications des query strings par défaut. Pour surveiller ces modifications, nous pouvons ajouter un watcher sur $route.query
et appeler $fetch
:
export default {
watch: {
'$route.query': '$fetch'
},
async fetch() {
// appelé aussi lors des modifications de query
}
}
Mise en cache
Nous pouvons utiliser la directive keep-alive
dans les composants <nuxt/>
et <nuxt-child>
pour sauvegarder le résultat des appels de fetch
dans les pages déjà visitées:
<template>
<nuxt keep-alive />
</template>
Nous pouvons aussi spécifier les props passées à <keep-alive>
en passant la prop keep-alive-props
au composant <nuxt>
.
<nuxt keep-alive :keep-alive-props="{ max: 10 }" />
Le code ci-dessus va garder en mémoire 10 composants page
.
Utiliser le hook activated
Nuxt va directement remplir this.$fetchState.timestamp
(horodatage) avec le dernier appel de fetch
(cela inclut le SSR). Nous pouvons utiliser cette propriété en combinaison avec le hook activated
pour ajouter 30 secondes de cache à fetch
:
<template> ... </template>
<script>
export default {
data() {
return {
posts: []
}
},
activated() {
// appeller fetch de nouveau si le dernier appel date de plus de 30 secondes
if (this.$fetchState.timestamp <= Date.now() - 30000) {
this.$fetch()
}
},
async fetch() {
this.posts = await fetch('https://api.nuxtjs.dev/posts').then(res =>
res.json()
)
}
}
</script>
La navigation à la même page ne va pas rappeler fetch
tant que le dernier call ne date pas d'au moins 30 secondes.
Async Data
asyncData
est seulement disponible pour les pages et nous n'avons donc pas accès à this
à l'intérieur du hook.La différence principale avec fetch
est que vous n'avez pas à gérer les status d'erreur ou en cours. Nuxt va attendre que le hook asyncData
soit terminé avant de procéder à la navigation sur la page suivante ou afficher la page d'erreur
Ce hook reçoit le contexte en tant que premier argument. Nous pouvons l'utiliser pour aller chercher de la data et Nuxt va automatiquement fusionner l'object retourné avec le data
du composant.
<template>
<h1>{{ project }}</h1>
</template>
<script>
export default {
async asyncData(context) {
return {
project: 'nuxt'
}
}
}
</script>
Dans les exemples qui suivent nous utilisons @nuxt/http , que nous recommandons pour aller récupérer de la data d'une API.
Écouter les changements de query
La méthode asyncData
n'est pas appelée par défaut sur les modifications liées aux query strings. Si nous souhaitons changer ce comportement, pour par exemple créer un composant de pagination, nous pouvons configurer des paramètres qui seront par la suite écoutés grâce à la propriété watchQuery
sur le composant de notre page.