14. Voorbeeld [nuxt-11]: aanpassing van de laadafbeelding
Standaard is de laadafbeelding van [nuxt] een voortgangsbalk. Het voorbeeld [nuxt-11] laat zien dat deze kan worden vervangen door een eigen laadafbeelding:

Het voorbeeld [nuxt-11] laat ook zien hoe je omgaat met laadfouten.

Het voorbeeld [nuxt-11] is in eerste instantie verkregen door het voorbeeld [nuxt-10] te kopiëren:

We gaan in [1] een plug-in voor de client toevoegen die tot taak heeft gebeurtenissen tussen componenten af te handelen.
14.1. De plug-in [event-bus]
De plug-in [event-bus] wordt zowel door de client als de server uitgevoerd, maar we zullen zien dat deze niet aan de serverzijde werkt. De code ervan is als volgt:
// er wordt een gebeurtenissenbus tussen de weergaven aangemaakt
import Vue from 'vue'
export default (context, inject) => {
// de gebeurtenissenbus
const eventBus = new Vue()
// een functie [eventBus] in de context injecteren
inject('eventBus', () => eventBus)
}
- regel 5: de gebeurtenissenbus is een instantie van de klasse [Vue]. Deze beschikt namelijk over de methoden om gebeurtenissen te beheren:
- [$emit]: om een gebeurtenis te genereren;
- [$on]: om te luisteren naar een specifieke gebeurtenis;
Deze gebeurtenissenbus zal slechts één gebeurtenis beheren, [loading], die door de pagina’s zal worden gebruikt om de animatie die het wachten op het einde van een asynchrone functie weergeeft, te starten of te stoppen;
- regel 7: we maken een functie [$eventBus] (1e argument) aan, die tot taak heeft het zojuist aangemaakte object [eventBus] (2e argument) terug te geven. Deze functie wordt in de context geïnjecteerd, zodat deze beschikbaar is in de objecten [context.app] en [this] van de pagina’s;
14.2. De lay-out [default.vue]
De lay-out [default.vue] verandert als volgt:
<template>
<div class="container">
<b-card>
<!-- een bericht -->
<b-alert show variant="success" align="center">
<h4>[nuxt-11] : personnalisation de l'attente, gestion des erreurs</h4>
</b-alert>
<!-- het huidige overzicht van de routering -->
<nuxt />
<!-- wordt geladen -->
<b-alert v-if="showLoading" show variant="light">
<strong>Requête au serveur de données en cours...</strong>
<div class="spinner-border ml-auto" role="status" aria-hidden="true"></div>
</b-alert>
<!-- fout bij het laden -->
<b-alert v-if="showErrorLoading" show variant="danger">
<strong>La requête au serveur de données a échoué : {{ errorLoadingMessage }}</strong>
</b-alert>
</b-card>
</div>
</template>
<script>
/* eslint-disable no-console */
export default {
name: 'App',
data() {
return {
showLoading: false,
showErrorLoading: false
}
},
// levenscyclus
beforeCreate() {
console.log('[default beforeCreate]')
},
created() {
console.log('[default created]')
// we luisteren naar de gebeurtenis [loading]
this.$eventBus().$on('loading', this.mShowLoading)
// evenals de gebeurtenis [errorLoadingMessage]
this.$eventBus().$on('errorLoading', this.mShowErrorLoading)
},
beforeMount() {
console.log('[default beforeMount]')
},
mounted() {
console.log('[default mounted]')
},
methods: {
// laadbeheer
mShowLoading(value) {
console.log('[default mShowLoading], showLoading=', value)
this.showLoading = value
},
// laadfout
mShowErrorLoading(value, errorLoadingMessage) {
console.log('[default mShowErrorLoading], showErrorLoading=', value, 'errorLoadingMessage=', errorLoadingMessage)
this.showErrorLoading = value
this.errorLoadingMessage = errorLoadingMessage
}
}
}
</script>
- regels 11-14: de wachtaanimatie. Deze wordt alleen weergegeven als de eigenschap [showLoading] waar is (regel 29);
- regels 16-18: het foutbericht bij het laden. Dit wordt alleen weergegeven als de eigenschap [showErrorLoading] (regel 30) waar is;
- regels 29-30: bij het eerste laden van de component worden zowel de wachtaanimatie als het foutbericht verborgen;
- regels 37-43: zodra de pagina is aangemaakt, luistert deze naar de gebeurtenis [loading] (1e argument) op de door de plug-in aangemaakte gebeurtenissenbus. Bij ontvangst laat de pagina de methode [mShowLoading] van regels 52-55 (2e argument) uitvoeren;
- regels 52-55: de waarde die door de methode [mShowLoading] wordt ontvangen, is een booleaanse waarde (true/false). Deze wordt gebruikt om het wachtbericht weer te geven of te verbergen;
- regels 41-42: zodra de pagina wordt aangemaakt, luistert deze naar de gebeurtenis [errorLoading] (1e argument) op de gebeurtenissenbus die door de plug-in is aangemaakt. Bij ontvangst laat de pagina de methode [mShowErrorLoading] uit de regels 57-61 (2e argument) uitvoeren;
- regel 57: de methode [mShowErrorLoading] ontvangt twee argumenten:
- het eerste argument is een booleaanse waarde (true/false) om het foutbericht weer te geven of te verbergen;
- het tweede argument is alleen aanwezig als er een fout is opgetreden. Het vertegenwoordigt de weer te geven foutmelding;
- uit de logboekvermeldingen op regel 53 en 58 blijkt dat de methoden [showLoading] en [showErrorLoading] niet aan de serverzijde worden uitgevoerd;
14.3. De pagina [page1]
De code van de pagina [page1] verandert als volgt:
<!-- weergave nr. 1 -->
<template>
<Layout :left="true" :right="true">
<!-- navigatie -->
<Navigation slot="left" />
<!-- bericht-->
<b-alert slot="right" show variant="primary"> Page 1 -- result={{ result }} </b-alert>
</Layout>
</template>
<script>
/* eslint-disable no-console */
/* eslint-disable nuxt/no-timing-in-fetch-data */
import Navigation from '@/components/navigation'
import Layout from '@/components/layout'
export default {
name: 'Page1',
// gebruikte componenten
components: {
Layout,
Navigation
},
// asynchrone gegevens
asyncData(context) {
// log
console.log('[page1 asyncData started]')
// begin wachttijd
context.app.$eventBus().$emit('loading', true)
// geen fout
context.app.$eventBus().$emit('errorLoading', false)
// een belofte wordt gedaan
return new Promise(function(resolve, reject) {
// een asynchrone functie wordt gesimuleerd
setTimeout(function() {
// einde wachten
context.app.$eventBus().$emit('loading', false)
// log
console.log('[page1 asyncData finished]')
// het asynchrone resultaat wordt geretourneerd – hier een willekeurig getal
resolve({ result: Math.floor(Math.random() * Math.floor(100)) })
}, 5000)
})
},
// levenscyclus
beforeCreate() {
console.log('[page1 beforeCreate]')
},
created() {
console.log('[page1 created]')
},
beforeMount() {
console.log('[page1 beforeMount]')
},
mounted() {
console.log('[page1 mounted]')
}
}
</script>
- de wijzigingen vinden plaats in de functie [asyncData] op de regels 26-47;
- regels 29-30: voordat de asynchrone functie begint, wordt de gebeurtenis [loading] verzonden naar de andere pagina’s van de applicatie. Ter herinnering: in [asyncData] hebben we nog geen toegang tot het object [this], dat nog niet is aangemaakt. We gebruiken daarom de context die als argument wordt doorgegeven aan de functie [asyncData] (regel 26);
- regel 30: de gebeurtenissenbus wordt gebruikt om aan te geven dat het laden gaat beginnen;
- regel 38: de gebeurtenissenbus wordt gebruikt om aan te geven dat het laden is voltooid;
Opmerking: Tijdens de uitvoering, wanneer de pagina [page1] bij de server wordt opgevraagd, wordt de laadafbeelding niet weergegeven. In de logbestanden is te zien dat de methode [default.mShowLoading] aan de serverzijde niet wordt aangeroepen. Hoe dan ook heeft het geen zin om de laadafbeelding te zien wanneer de pagina bij de server wordt opgevraagd. De server stuurt de pagina pas naar de browser van de klant zodra de functie [asyncData] is voltooid. De laadafbeelding is dan overbodig. Dit geldt voor alle pagina’s van de applicatie die rechtstreeks bij de server worden opgevraagd.
14.4. De pagina [index]
De code van de pagina [index] is als volgt:
<!-- hoofdpagina -->
<template>
<Layout :left="true" :right="true">
<!-- navigatie -->
<Navigation slot="left" />
<!-- bericht-->
<b-alert slot="right" show variant="warning">
Home
</b-alert>
</Layout>
</template>
<script>
/* eslint-disable no-undef */
/* eslint-disable no-console */
/* eslint-disable nuxt/no-env-in-hooks */
/* eslint-disable nuxt/no-timing-in-fetch-data */
import Navigation from '@/components/navigation'
import Layout from '@/components/layout'
export default {
name: 'Home',
// gebruikte componenten
components: {
Layout,
Navigation
},
// asynchrone gegevens
asyncData(context) {
// log
console.log('[page1 asyncData started]')
// begin wachttijd
context.app.$eventBus().$emit('loading', true)
// geen fout
context.app.$eventBus().$emit('errorLoading', false)
// een belofte wordt gedaan
return new Promise(function(resolve, reject) {
// een asynchrone functie wordt gesimuleerd
setTimeout(function() {
// einde wachten
context.app.$eventBus().$emit('loading', false)
// log
console.log('[page1 asyncData finished]')
// er wordt een fout geretourneerd
reject(new Error("le serveur n'a pas répondu assez vite"))
}, 5000)
}).catch((e) => context.error({ statusCode: 500, message: e.message }))
},
// levenscyclus
beforeCreate() {
console.log('[home beforeCreate]')
},
created() {
console.log('[home created]')
},
beforeMount() {
console.log('[home beforeMount]')
},
mounted() {
console.log('[home mounted]')
// geen fout
this.$eventBus().$emit('errorLoading', false)
}
}
</script>
- regels 30-49: de functie [asyncData] is identiek aan die van de pagina [page1], op één detail na: op regel 46 wordt de asynchrone functie bij een fout beëindigd (gebruik van de methode [reject]);
- regel 46: de parameter van de functie [reject] is een instantie van de klasse [Error]. De parameter van de constructor [Error] is het foutbericht;
- regel 48: deze fout wordt opgevangen door de methode [catch] van [Promise], die de fout als parameter ontvangt. Vervolgens wordt de functie [context.error] gebruikt om de fout te melden. De parameter van de functie [context.error] is een object met in dit geval twee eigenschappen:
- [statusCode]: een foutcode HTTP;
- [message]: een foutmelding;
Of [asyncData] nu door de client of de server wordt uitgevoerd, in geval van een fout [context.error] geeft [nuxt] de pagina [layouts / error.vue] weer:

Hoewel het om een pagina gaat, wordt de pagina [error.vue] gezocht in de map [layouts] (misschien om te voorkomen dat deze in de routes van de applicatie wordt opgenomen?). Hier is de pagina [error.vue] als volgt:
<!-- definitie HTML van de weergave -->
<template>
<!-- pagina-indeling -->
<Layout :left="true" :right="true">
<!-- waarschuwing in de rechterkolom -->
<template slot="right">
<!-- bericht op gele achtergrond -->
<b-alert show variant="danger" align="center">
<h4>L'erreur suivante s'est produite : {{ JSON.stringify(error) }}</h4>
</b-alert>
</template>
<!-- navigatiemenu in de linkerkolom -->
<Navigation slot="left" />
</Layout>
</template>
<script>
/* eslint-disable no-undef */
/* eslint-disable no-console */
/* eslint-disable nuxt/no-env-in-hooks */
import Layout from '@/components/layout'
import Navigation from '@/components/navigation'
export default {
name: 'Error',
// gebruikte componenten
components: {
Layout,
Navigation
},
// eigenschap [props]
props: { error: { type: Object, default: () => 'waiting ...' } },
// levenscyclus
beforeCreate() {
// client en server
console.log('[error beforeCreate]')
},
created() {
// client en server
console.log('[error created, error=]', this.error)
},
beforeMount() {
// alleen client
console.log('[error beforeMount]')
},
mounted() {
// alleen client
console.log('[error mounted]')
}
}
</script>
Wanneer [nuxt] de pagina [error.vue] weergeeft, draagt het de eigenschap [props], de fout die is opgetreden (regel 33), aan deze pagina over. Als de fout is veroorzaakt door [context.error(objet1)], krijgt de eigenschap [props] van de pagina [error.vue] de waarde [objet1]. In de documentatie van [nuxt] staat dat [objet1] ten minste de attributen van [statusCode, message] moet hebben. Regel 9 geeft de tekenreeks jSON weer van het ontvangen object [objet1].
14.5. De pagina [page2]
De pagina [page2] toont een andere manier om de fout af te handelen:
- in [page1] wordt de fout weergegeven op een aparte pagina, [error.vue];
- in [page2] wordt de fout weergegeven op de pagina [page2] die de fout heeft veroorzaakt;
De code van [page2] is als volgt:
<!-- weergave nr. 2 -->
<template>
<Layout :left="true" :right="true">
<!-- navigatie -->
<Navigation slot="left" />
<!-- bericht -->
<b-alert slot="right" show variant="secondary">
Page 2
</b-alert>
</Layout>
</template>
<script>
/* eslint-disable no-console */
/* eslint-disable nuxt/no-timing-in-fetch-data */
import Navigation from '@/components/navigation'
import Layout from '@/components/layout'
export default {
name: 'Page2',
// gebruikte componenten
components: {
Layout,
Navigation
},
// asynchrone gegevens
asyncData(context) {
// log
console.log('[page2 asyncData started]')
// begin wachttijd
context.app.$eventBus().$emit('loading', true)
// geen fout
context.app.$eventBus().$emit('errorLoading', false)
// een belofte wordt gedaan
return new Promise(function(resolve, reject) {
// een asynchrone functie wordt gesimuleerd
setTimeout(function() {
// einde wachten
context.app.$eventBus().$emit('loading', false)
// er wordt willekeurig een fout gegenereerd
const errorLoadingMessage = "le serveur n'a pas répondu assez vite"
// succesvol voltooid
resolve({ showErrorLoading: true, errorLoadingMessage })
// log
console.log('[page2 asyncData finished]')
}, 5000)
})
},
// levenscyclus
beforeCreate() {
console.log('[page2 beforeCreate]')
},
created() {
console.log('[page2 created]')
},
beforeMount() {
console.log('[page2 beforeMount]')
},
mounted() {
console.log('[page2 mounted]')
// client
if (this.showErrorLoading) {
console.log('[page2 mounted, showErrorLoading=true]')
this.$eventBus().$emit('errorLoading', true, this.errorLoadingMessage)
}
}
}
</script>
Opnieuw voegen we een functie [asyncData] toe aan de paginacode en net als bij [index] zal [page2] een fout genereren die we deze keer anders zullen afhandelen.
- regel 44: zowel de server als de client sluiten de promise succesvol af door het resultaat [{ showErrorLoading: true, errorLoadingMessage }] terug te geven. We weten dat dit tot gevolg heeft dat de eigenschappen [showerrorLoading, errorLoadingMessage] worden opgenomen in de eigenschappen [data] van de pagina en dat de client deze eigenschappen zal ontvangen;
- regels 60-67: we weten dat de functie [mounted] alleen door de client wordt uitgevoerd;
- regel 63: de client controleert of de eigenschap [showErrorLoading] is ingesteld (door de server of de client, afhankelijk van het geval). Zo ja, dan genereert hij de gebeurtenis [‘errorLoading’] (regel 65) zodat de pagina [default] de foutmelding [this.errorLoadingMessage] weergeeft. Uiteindelijk verstuurt de server een pagina zonder dat er een foutmelding wordt weergegeven. Deze wordt op het laatste moment door de client weergegeven wanneer de pagina wordt ‘opgebouwd’;
14.6. Exécution
14.6.1. [nuxt.config]
Het uitvoerbestand [nuxt.config.js] ziet er als volgt uit:
export default {
mode: 'universal',
/*
** Headers of the page
*/
head: {
title: 'Introduction à [nuxt.js]',
meta: [
{ charset: 'utf-8' },
{ name: 'viewport', content: 'width=device-width, initial-scale=1' },
{
hid: 'description',
name: 'description',
content: 'ssr routing loading asyncdata middleware plugins store'
}
],
link: [{ rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' }]
},
/*
** Customize the progress-bar color
*/
loading: false,
/*
** Global CSS
*/
css: [],
/*
** Plugins to load before mounting the App
*/
plugins: [{ src: '@/plugins/event-bus' }],
/*
** Nuxt.js dev-modules
*/
buildModules: [
// Doc: https://github.com/nuxt-community/eslint-module
'@nuxtjs/eslint-module'
],
/*
** Nuxt.js modules
*/
modules: [
// Doc: https://bootstrap-vue.js.org
'bootstrap-vue/nuxt',
// Doc: https://axios.nuxtjs.org/usage
'@nuxtjs/axios'
],
/*
** Axios module configuration
** See https://axios.nuxtjs.org/options
*/
axios: {},
/*
** Build configuration
*/
build: {
/*
** You can extend webpack config here
*/
extend(config, ctx) {}
},
// broncodemap
srcDir: 'nuxt-11',
// router
router: {
// hoofdmap van de applicatie URL
base: '/nuxt-11/'
},
// server
server: {
// servicepoort, standaard 3000
port: 81,
// netwerkadressen waarop wordt geluisterd, standaard localhost: 127.0.0.1
// 0.0.0.0 = alle netwerkadressen van de machine
host: 'localhost'
}
}
- regel 22: we stellen de eigenschap [loading] in op [false], zodat [nuxt] zijn standaard laadafbeelding niet gebruikt;
- regel 31: de plug-in die de gebeurtenissenbus definieert;
14.6.2. L, een pagina [index] die door de server wordt uitgevoerd
Laten we de pagina [index] bij de server opvragen (we typen de URL [http://localhost:81/nuxt-11/] handmatig in). De pagina die door de clientbrowser wordt weergegeven, is de volgende:

De logbestanden zien er als volgt uit:

- in [3] zien we dat de server de pagina [error.vue] verstuurt;
- in [4] is te zien dat de client eveneens de pagina [error] weergeeft met dezelfde foutmelding als de server;
- we kunnen opmerken dat de methode [mShowLoading] van de pagina [default] niet is aangeroepen aan de serverzijde, terwijl de pagina [index] een wachtrij had geactiveerd. Deze methode wordt aangeroepen bij ontvangst van een gebeurtenis en blijkbaar is de gebeurtenisafhandeling niet geïmplementeerd aan de serverzijde;
Laten we de broncode bekijken van de pagina die door de clientbrowser is ontvangen:
<!doctype html>
<html data-n-head-ssr>
<head>
<title>Introduction à [nuxt.js]</title>
<meta data-n-head="ssr" charset="utf-8">
<meta data-n-head="ssr" name="viewport" content="width=device-width, initial-scale=1">
<meta data-n-head="ssr" data-hid="description" name="description" content="ssr routing loading asyncdata middleware plugins store">
<link data-n-head="ssr" rel="icon" type="image/x-icon" href="/favicon.ico">
<base href="/nuxt-11/">
<link rel="preload" href="/nuxt-11/_nuxt/runtime.js" as="script">
<link rel="preload" href="/nuxt-11/_nuxt/commons.app.js" as="script">
<link rel="preload" href="/nuxt-11/_nuxt/vendors.app.js" as="script">
<link rel="preload" href="/nuxt-11/_nuxt/app.js" as="script">
...
</head>
<body>
<div data-server-rendered="true" id="__nuxt">
<div id="__layout">
<div class="container">
<div class="card">
<div class="card-body">
<div role="alert" aria-live="polite" aria-atomic="true" align="center" class="alert alert-success">
<h4>[nuxt-11] : personnalisation de l'attente, gestion des erreurs</h4>
</div>
<div>
<div class="row">
<div class="col-2">
<ul class="nav flex-column">
<li class="nav-item">
<a href="/nuxt-11/" target="_self" class="nav-link active nuxt-link-active">
Home
</a>
</li>
<li class="nav-item">
<a href="/nuxt-11/page1" target="_self" class="nav-link">
Page 1
</a>
</li>
<li class="nav-item">
<a href="/nuxt-11/page2" target="_self" class="nav-link">
Page 2
</a>
</li>
</ul>
</div> <div class="col-10"><div role="alert" aria-live="polite" aria-atomic="true" align="center" class="alert alert-danger">
<h4>L'erreur suivante s'est produite : {"statusCode":500,"message":"le serveur n'a pas répondu assez vite"}</h4>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<script>window.__NUXT__ = (function (a, b, c, d) {
d.statusCode = 500; d.message = "le serveur n'a pas répondu assez vite";
return {
layout: "default", data: [d], error: d, serverRendered: true,
logs: [
{ date: new Date(1575047424168), args: ["[event-bus créé]"], type: a, level: b, tag: c },
{ date: new Date(1575047424175), args: ["[page1 asyncData started]"], type: a, level: b, tag: c },
{ date: new Date(1575047429455), args: ["[page1 asyncData finished]"], type: a, level: b, tag: c },
{ date: new Date(1575047429515), args: ["[default beforeCreate]"], type: a, level: b, tag: c },
{ date: new Date(1575047429675), args: ["[default created]"], type: a, level: b, tag: c },
{ date: new Date(1575047430157), args: ["[error beforeCreate]"], type: a, level: b, tag: c },
{ date: new Date(1575047430246), args: ["[error created, error=]", "{ statusCode: 500,\n message: 'le serveur n\\'a pas répondu assez vite' }"], type: a, level: b, tag: c }]
}
}("log", 2, "", {}));</script>
<script src="/nuxt-11/_nuxt/runtime.js" defer></script>
<script src="/nuxt-11/_nuxt/commons.app.js" defer></script>
<script src="/nuxt-11/_nuxt/vendors.app.js" defer></script>
<script src="/nuxt-11/_nuxt/app.js" defer></script>
</body>
</html>
- regel 57: we zien dat de server een object [d] heeft verzonden, dat de fout weergeeft die aan de serverzijde is opgetreden;
- regel 59: we zien een eigenschap [error] met als waarde het object [d]. We kunnen ons voorstellen dat het de aanwezigheid is van de eigenschap [error] in de door de server verzonden pagina die ervoor zorgt dat de clientscripts de pagina [error.vue] weergeven met de fout [error];
14.6.3. De pagina [page1] die door de server wordt uitgevoerd
We voeren handmatig URL [http://localhost:81/nuxt-11/page1] in. Na 5 seconden geeft de browser de volgende pagina weer:

De weergegeven logbestanden zijn als volgt:

- in [1], de logbestanden van de server. We zien dat de methode [mShowLoading] van de pagina [default] niet is aangeroepen;
- in [2], de logbestanden van de client;
14.6.4. De pagina [page2] die door de server wordt uitgevoerd
We voeren URL en [http://localhost:81/nuxt-11/page2] handmatig in. Na 5 seconden geeft de browser de volgende pagina weer:

Laten we de logs bekijken die in de browser worden weergegeven:

- in [1], de logbestanden van de server. We herinneren eraan dat de server de eigenschappen [showErrorLoading, errorLoadingMessage] in de naar de clientbrowser verzonden pagina heeft opgenomen. We weten dat deze eigenschappen vervolgens worden geïntegreerd in de [data] van de door de client weergegeven pagina
- in [3]: wanneer de pagina [page2] wordt geladen, vindt deze de eigenschap [showErrorLoading] op ‘waar’ staan. Vervolgens stuurt deze een gebeurtenis naar de pagina [default], zodat deze de door de server [4] verzonden foutmelding weergeeft;
14.6.5. De pagina [index] die door de client wordt uitgevoerd
We gebruiken nu de navigatielinks om de drie pagina’s weer te geven. Alle pagina’s die door de client worden weergegeven, zijn identiek aan die welke door de server worden weergegeven. Het enige verschil is dat telkens de laadafbeelding wordt weergegeven totdat de 5 seconden voorbij zijn.
We beginnen met de pagina [index]. De afbeelding die aangeeft dat er gewacht wordt tot het verstrijken van de 5 seconden, wordt dan weergegeven:

en na 5 seconden verschijnt de volgende pagina:

De uiteindelijke pagina is dus identiek aan die welke aan de serverzijde wordt weergegeven.

Laten we nog eens kijken naar de functie [asyncData] van de pagina [index]:
asyncData(context) {
// log
console.log('[page1 asyncData started]')
// begin afwachten
context.app.$eventBus().$emit('loading', true)
// geen fout
context.app.$eventBus().$emit('errorLoading', false)
// er wordt een belofte gedaan
return new Promise(function(resolve, reject) {
// een asynchrone functie wordt gesimuleerd
setTimeout(function() {
// einde wachten
context.app.$eventBus().$emit('loading', false)
// log
console.log('[page1 asyncData finished]')
// er wordt een fout geretourneerd
reject(new Error("le serveur n'a pas répondu assez vite"))
}, 5000)
}).catch((e) => context.error({ statusCode: 500, message: e.message }))
}
De logbestanden van de client zijn als volgt:

- in [1] wordt de functie [asyncData] gestart;
- in [2] wordt de wachtafbeelding gestart;
- bij [2-3], zien we dat de pagina [default] de gebeurtenissen [loading, true], [2] en [errorLoading, false] heeft ontvangen, verzonden door de functie [asyncData] van de pagina [index] (regels 5 en 7);
- in [4], einde van het wachten. De pagina [default] heeft de gebeurtenis [loading, false] ontvangen, verzonden door de pagina [index] (regel 13);
- in [5] heeft de functie [asyncData] haar werk voltooid;
- omdat de functie [asyncData] een fout heeft veroorzaakt met [context.error] (regel 19), wordt de pagina [error] weergegeven als [6];
14.6.6. De pagina [page1] wordt door de client uitgevoerd
Na 5 seconden te hebben gewacht, geeft de client de volgende pagina weer:

Laten we de code van de functie [asyncData] uit [page1] nog eens bekijken:
asyncData(context) {
// log
console.log('[page1 asyncData started]')
// begin van het wachten
context.app.$eventBus().$emit('loading', true)
// geen fout
context.app.$eventBus().$emit('errorLoading', false)
// er wordt een belofte geretourneerd
return new Promise(function(resolve, reject) {
// een asynchrone functie wordt gesimuleerd
setTimeout(function() {
// einde wachten
context.app.$eventBus().$emit('loading', false)
// log
console.log('[page1 asyncData finished]')
// het asynchrone resultaat wordt geretourneerd – hier een willekeurig getal
resolve({ result: Math.floor(Math.random() * Math.floor(100)) })
}, 5000)
})
},
De logbestanden zien er als volgt uit:

14.6.7. De pagina [page2] die door de client wordt uitgevoerd
Na 5 seconden wachten geeft de client de volgende pagina weer:

Laten we nog eens kijken naar de code van de functies [asyncData] en [mounted] uit [page2]:
asyncData(context) {
// log
console.log('[page2 asyncData started]')
// begin wachten
context.app.$eventBus().$emit('loading', true)
// geen fout
context.app.$eventBus().$emit('errorLoading', false)
// we geven een belofte af
return new Promise(function(resolve, reject) {
// we simuleren een asynchrone functie
setTimeout(function() {
// einde wachten
context.app.$eventBus().$emit('loading', false)
// er wordt willekeurig een fout gegenereerd
const errorLoadingMessage = "le serveur n'a pas répondu assez vite"
// succesvol voltooid
resolve({ showErrorLoading: true, errorLoadingMessage })
// log
console.log('[page2 asyncData finished]')
}, 5000)
})
}
mounted() {
console.log('[page2 mounted]')
// client
if (this.showErrorLoading) {
console.log('[page2 mounted, showErrorLoading=true]')
this.$eventBus().$emit('errorLoading', true, this.errorLoadingMessage)
}
}
De logbestanden zien er als volgt uit:

- in [1] heeft de pagina [default] de gebeurtenis [showErrorLoading, true] ontvangen, verzonden door [page2] (regel 29), waarin wordt gevraagd om de foutmelding weer te geven;