12. project [vuejs-10]: plug-in [dao], asynchrone verzoeken HTTP
De projectstructuur van project [vuejs-10] is als volgt:

Het project [vuejs-10] toont een component die een verzoek HTTP naar een externe server verstuurt. De gebruikte architectuur is als volgt:

Een component [Vue.js] gebruikt de laag [dao] om te communiceren met de server voor belastingberekening.
12.1. Installatie van de afhankelijkheden
De applicatie [vuejs-10] maakt gebruik van de bibliotheek [axios] om asynchrone verzoeken naar de belastingberekeningsserver te verzenden. We moeten deze afhankelijkheid installeren:

- in [4-5], de regel die na de installatie van de bibliotheek [axios] aan het bestand [package.json] is toegevoegd: [1-3] ;
12.2. De klasse [Dao]
De klasse [Dao] is de klasse die in paragraaf [La classe Dao] is ontwikkeld. We geven deze hier nogmaals weer ter herinnering:
'use strict';
// imports
import qs from 'qs'
// klasse [Dao]
class Dao {
// constructor
constructor(axios) {
this.axios = axios;
// sessiecookie
this.sessionCookieName = "PHPSESSID";
this.sessionCookie = '';
}
// sessie starten
async initSession() {
// verzoekopties HHTP [get /main.php?action=init-session&type=json]
const options = {
method: "GET",
// parameters van de URL
params: {
action: 'init-session',
type: 'json'
}
};
// uitvoering van de query HTTP
return await this.getRemoteData(options);
}
async authentifierUtilisateur(user, password) {
// opties van de aanvraag HHTP [post /main.php?action=authentifier-utilisateur]
const options = {
method: "POST",
headers: {
'Content-type': 'application/x-www-form-urlencoded',
},
// hoofdtekst van het POST
data: qs.stringify({
user: user,
password: password
}),
// parameters van de URL
params: {
action: 'authentifier-utilisateur'
}
};
// uitvoering van de query HTTP
return await this.getRemoteData(options);
}
async getAdminData() {
// opties van de aanvraag HHTP [get /main.php?action=get-admindata]
const options = {
method: "GET",
// parameters van de URL
params: {
action: 'get-admindata'
}
};
// uitvoering van de query HTTP
const data = await this.getRemoteData(options);
// resultaat
return data;
}
async getRemoteData(options) {
// voor de sessiecookie
if (!options.headers) {
options.headers = {};
}
options.headers.Cookie = this.sessionCookie;
// uitvoering van de aanvraag HTTP
let response;
try {
// asynchrone aanvraag
response = await this.axios.request('main.php', options);
} catch (error) {
// de parameter [error] is een uitzondering – deze kan verschillende vormen aannemen
if (error.response) {
// het antwoord van de server staat in [error.response]
response = error.response;
} else {
// de fout wordt opnieuw gegenereerd
throw error;
}
}
// response is het volledige antwoord HTTP van de server (headers HTTP + het antwoord zelf)
// de sessiecookie wordt opgehaald, indien deze bestaat
const setCookie = response.headers['set-cookie'];
if (setCookie) {
// setCookie is een array
// we zoeken de sessiecookie in deze array
let trouvé = false;
let i = 0;
while (!trouvé && i < setCookie.length) {
// we zoeken naar de sessiecookie
const results = RegExp('^(' + this.sessionCookieName + '.+?);').exec(setCookie[i]);
if (results) {
// de sessiecookie wordt opgeslagen
// eslint-disable-next-line require-atomic-updates
this.sessionCookie = results[1];
// gevonden
trouvé = true;
} else {
// volgend element
i++;
}
}
}
// het antwoord van de server staat in [response.data]
return response.data;
}
}
// export van de klasse
export default Dao;
Het project [vuejs-10] maakt uitsluitend gebruik van de asynchrone methode [initSession] uit de regels 18-30. Ter herinnering: de klasse [Dao] wordt geïnstantieerd met een parameter [axios] (regel 10), die door de aanroepende code wordt geïnitialiseerd. Deze aanroepende code is in dit geval het script [./main.js].
12.3. De plug-in [pluginDao]
De plug-in [pluginDao] ziet er als volgt uit:
export default {
install(Vue, dao) {
// voegt een eigenschap [$dao] toe aan de klasse Vue
Object.defineProperty(Vue.prototype, '$dao', {
// wanneer naar Vue.$dao wordt verwezen, wordt de tweede parameter [dao] weergegeven
get: () => dao,
})
}
}
Als we terugdenken aan de uitleg die werd gegeven voor de plug-in [event-bus], zien we dat de plug-in [pluginDao] in de klasse/functie [Vue] een nieuwe eigenschap aanmaakt met de naam [$dao]. Deze eigenschap zal (dat moet nog blijken) als waarde het object hebben dat door het script [./Dao] wordt geëxporteerd, d.w.z. de voorgaande klasse [Dao].
12.4. Het hoofdscript [main.js]
De code van het hoofdscript [main.js] is als volgt:
// imports
import Vue from 'vue'
import App from './App.vue'
import axios from 'axios';
// plugins
import BootstrapVue from 'bootstrap-vue'
Vue.use(BootstrapVue);
// bootstrap
import 'bootstrap/dist/css/bootstrap.css'
import 'bootstrap-vue/dist/bootstrap-vue.css'
// laag [dao]
import Dao from './Dao';
// axios-configuratie
axios.defaults.timeout = 2000;
axios.defaults.baseURL = 'http://localhost/php7/scripts-web/impots/version-14';
axios.defaults.withCredentials = true;
// instantiëring van laag [dao]
const dao = new Dao(axios);
// plugin [dao]
import pluginDao from './plugins/dao'
Vue.use(pluginDao, dao)
// configuratie
Vue.config.productionTip = false
// projectinstantie [App]
new Vue({
render: h => h(App),
}).$mount('#app')
Het script [main.js]:
- instantiëert de laag [dao] op de regels 14-21;
- integreert de plug-in [pluginDao] op de regels 24-25;
- regel 15: de klasse [Dao] wordt geïmporteerd;
- regels 17-18: het object [axios] wordt geconfigureerd, dat de verzoeken HTTP uitvoert. Dit object wordt geïmporteerd op regel 4;
- regel 17: definitie van een [timeout] van 2 seconden;
- regel 18: het URL-object van de belastingberekeningsserver;
- regel 19: om cookies met de server te kunnen uitwisselen;
- regels 24-25: gebruik van de plug-in [pluginDao]
- regel 24: de plug-in importeren;
- regel 25: integratie van de plug-in. We zien dat de tweede parameter van de methode [Vue.use] de referentie is van de laag [dao] die op regel 21 is gedefinieerd. Om deze reden zal de eigenschap [Vue.$dao] in alle instanties van de klasse/functie [Vue], d.w.z. in alle componenten [Vue.js], verwijzen naar de laag [dao];
12.5. De hoofdweergave [App.vue]
De code van de hoofdweergave [App] is als volgt:
<template>
<div class="container">
<b-card>
<!-- bericht -->
<b-alert show variant="success" align="center">
<h4>[vuejs-10] : plugin [dao], requêtes HTTP asynchrones</h4>
</b-alert>
<!-- component die een asynchrone aanvraag doet aan de belastingberekeningsserver-->
<Component1 @error="doSomethingWithError" @endWaiting="endWaiting" @beginWaiting="beginWaiting" />
<!-- weergave van een eventuele foutmelding -->
<b-alert show
variant="danger"
v-if="showError">Evénement [error] intercepté par [App]. Valeur reçue = {{error}}</b-alert>
<!-- wachtbericht met een spinner -->
<b-alert show v-if="showWaiting" variant="light">
<strong>Requête au serveur de calcul d'impôt en cours...</strong>
<b-spinner variant="primary" label="Spinning"></b-spinner>
</b-alert>
</b-card>
</div>
</template>
<script>
import Component1 from "./components/Component1";
export default {
name: "app",
// status van de component
data() {
return {
// beheert de laadindicator
showWaiting: false,
// de weergave van de fout controleren
showError: false,
// de onderschepte fout
error: {}
};
},
// gebruikte componenten
components: {
Component1
},
// methoden voor gebeurtenisbeheer
methods: {
// begin van de wachttijd
beginWaiting() {
// de wachttijd wordt weergegeven
this.showWaiting = true;
// de foutmelding wordt verborgen
this.showError = false;
},
// einde wachtrij
endWaiting() {
// de wachtrij wordt verborgen
this.showWaiting = false;
},
// foutafhandeling
doSomethingWithError(error) {
// er wordt genoteerd dat er een fout is opgetreden
this.error = error;
// de foutmelding wordt weergegeven
this.showError = true;
}
}
};
</script>
Opmerkingen
- regel 9: [Component1] is de component die de asynchrone aanvraag HTTP uitvoert. Deze kan drie gebeurtenissen genereren:
- [beginWaiting]: het verzoek wordt uitgevoerd. Er moet een wachtbericht voor de gebruiker worden weergegeven;
- [endWaiting]: de aanvraag is voltooid. Het wachten moet worden beëindigd;
- [error]: de aanvraag is mislukt. Er moet een foutmelding worden weergegeven;
- regels 10-13: de melding die het eventuele foutbericht weergeeft. Deze wordt aangestuurd door de booleaanse variabele [showError] op regel 33. De fout op regel 35 wordt hier weergegeven;
- regels 14-18: de melding die het wachtbericht met een spinner weergeeft. Deze wordt aangestuurd door de booleaanse variabele [showWaiting] op regel 47;
- regels 45-50: [beginWaiting] is de methode die wordt uitgevoerd bij ontvangst van de gebeurtenis [beginWaiting]. Deze geeft het wachtbericht weer (regel 47) en verbergt het foutbericht (regel 49) voor het geval dit zichtbaar zou zijn als gevolg van een eerdere bewerking;
- regels 52-55: [endWaiting] is de methode die wordt uitgevoerd bij ontvangst van de gebeurtenis [endWaiting]. Deze methode verbergt het wachtbericht (regel 54);
- regels 57-62: [doSomethingWithError] is de methode die wordt uitgevoerd bij ontvangst van de gebeurtenis [error]. Deze methode registreert de ontvangen fout (regel 59) en geeft de foutmelding weer (regel 61);
12.6. De component [Component1]
De code van de component [Component1] is als volgt:
<template>
<b-row>
<b-col>
<b-alert show
variant="warning"
v-if="showMsg">Valeur reçue du serveur = {{data}}</b-alert>
</b-col>
</b-row>
</template>
<script>
export default {
name: "component1",
// status van de component
data() {
return {
showMsg: false
};
},
// methoden voor gebeurtenisafhandeling
methods: {
// verwerking van de gegevens die van de server zijn ontvangen
doSomethingWithData(data) {
// de ontvangen gegevens worden opgeslagen
this.data = data;
// we geven ze weer
this.showMsg = true;
}
},
// de component is zojuist aangemaakt
created() {
// de sessie met de server wordt geïnitialiseerd – asynchrone aanvraag
// de belofte die door de methoden van de laag wordt geretourneerd, wordt gebruikt [dao]
// het begin van de bewerking wordt gemeld
this.$emit("beginWaiting");
// de asynchrone bewerking wordt gestart
this.$dao
// hier gaat het om het initialiseren van een sessie jSON met de belastingberekeningsserver
.initSession()
// methode die de ontvangen gegevens verwerkt bij succes
.then(data => {
// de ontvangen gegevens worden verwerkt
this.doSomethingWithData(data);
})
// methode die de fout verwerkt in geval van een fout
.catch(error => {
// de fout wordt doorgegeven aan de bovenliggende component
this.$emit("error", error.message);
}).finally(() => {
// einde van het wachten
this.$emit("endWaiting");
})
}
};
</script>
Opmerkingen
- regels 4-6: de component bestaat uit één enkele melding die de door de belastingberekeningsserver geretourneerde waarde weergeeft, maar alleen als het verzoek HTTP succesvol is. Deze melding wordt aangestuurd door de booleaanse variabele [showMsg] in regel 17;
- regels 31-53: de aanvraag HTTP wordt uitgevoerd zodra de component is aangemaakt. De code hiervoor wordt dus in de methode [created] op regel 31 geplaatst;
- regel 35: aan de bovenliggende component wordt aangegeven dat de asynchrone aanvraag gaat starten;
- regels 37-39: de methode [this.$dao.initSession] wordt uitgevoerd. Deze initialiseert een sessie jSON met de server voor belastingberekening. Het onmiddellijke resultaat van deze methode is een [Promise];
- regels 41-44: deze code wordt uitgevoerd wanneer de server het resultaat zonder fouten heeft teruggestuurd. Het resultaat van de server staat in [data]. In regel 43 wordt de methode [doSomethingWithData] gevraagd om dit resultaat te verwerken;
- regels 46-49: deze code wordt uitgevoerd als er een fout optreedt tijdens de uitvoering van de aanvraag. Op regel 48 wordt aan de bovenliggende component gemeld dat er een fout is opgetreden en wordt het foutbericht [error.message] doorgegeven;
- regels 49-52: deze code wordt in alle gevallen uitgevoerd. Aan de bovenliggende component wordt gemeld dat de aanvraag HTTP is voltooid;
- regels 23-28: de methode [doSomethingWithData] is de methode die de door de server verzonden gegevens [data] verwerkt. In regel 25 worden deze gegevens opgeslagen en in regel 27 worden ze weergegeven;
12.7. Uitvoering van het project

Als bij het starten van het project de belastingberekeningsserver niet is gestart, krijgt men het volgende resultaat:

Laten we de server [Laragon] starten (zie https://tahe.developpez.com/tutoriels-cours/php7) en de bovenstaande pagina opnieuw laden. Het resultaat is dan als volgt:

Opmerking: we gebruiken hier versie 14 van de belastingberekeningsserver, zoals gedefinieerd op https://tahe.developpez.com/tutoriels-cours/php7.