12. Projekt [vuejs-10]: [dao]-Plugin, asynchrone HTTP-Anfragen
Die Verzeichnisstruktur des Projekts [vuejs-10] sieht wie folgt aus:

Das Projekt [vuejs-10] demonstriert eine Komponente, die eine HTTP-Anfrage an einen Remote-Server sendet. Die verwendete Architektur sieht wie folgt aus:

Eine [Vue.js]-Komponente nutzt die [dao]-Schicht, um mit dem Steuerberechnungsserver zu kommunizieren.
12.1. Installation der Abhängigkeiten
Die [vuejs-10]-Anwendung nutzt die [axios]-Bibliothek, um asynchrone Anfragen an den Steuerberechnungsserver zu stellen. Wir müssen diese Abhängigkeit installieren:

- in [4-5] die Zeile, die nach der Installation der [axios]-Bibliothek [1-3] zur Datei [package.json] hinzugefügt wurde;
12.2. Die [Dao]-Klasse
Die [Dao]-Klasse ist diejenige, die im Abschnitt [Die Dao-Klasse] entwickelt wurde. Wir fügen sie hier als Referenz ein:
'use strict';
// imports
import qs from 'qs'
// dao] class
class Dao {
// manufacturer
constructor(axios) {
this.axios = axios;
// session cookie
this.sessionCookieName = "PHPSESSID";
this.sessionCookie = '';
}
// init session
async initSession() {
// query options HHTP [get /main.php?action=init-session&type=json]
const options = {
method: "GET",
// URL parameters
params: {
action: 'init-session',
type: 'json'
}
};
// execute query HTTP
return await this.getRemoteData(options);
}
async authentifierUtilisateur(user, password) {
// query options HHTP [post /main.php?action=authenticate-user]
const options = {
method: "POST",
headers: {
'Content-type': 'application/x-www-form-urlencoded',
},
// body of POST
data: qs.stringify({
user: user,
password: password
}),
// URL parameters
params: {
action: 'authentifier-utilisateur'
}
};
// execute query HTTP
return await this.getRemoteData(options);
}
async getAdminData() {
// query options HHTP [get /main.php?action=get-admindata]
const options = {
method: "GET",
// URL parameters
params: {
action: 'get-admindata'
}
};
// execute query HTTP
const data = await this.getRemoteData(options);
// result
return data;
}
async getRemoteData(options) {
// for the session cookie
if (!options.headers) {
options.headers = {};
}
options.headers.Cookie = this.sessionCookie;
// execute query HTTP
let response;
try {
// asynchronous request
response = await this.axios.request('main.php', options);
} catch (error) {
// the [error] parameter is an exception instance - it can take various forms
if (error.response) {
// the server response is in [error.response]
response = error.response;
} else {
// error restart
throw error;
}
}
// response is the entire HTTP response from the server (HTTP headers + response itself)
// retrieve the session cookie if it exists
const setCookie = response.headers['set-cookie'];
if (setCookie) {
// setCookie is an array
// look for the session cookie in this table
let trouvé = false;
let i = 0;
while (!trouvé && i < setCookie.length) {
// look for the session cookie
const results = RegExp('^(' + this.sessionCookieName + '.+?);').exec(setCookie[i]);
if (results) {
// the session cookie is stored
// eslint-disable-next-line require-atomic-updates
this.sessionCookie = results[1];
// we found
trouvé = true;
} else {
// next item
i++;
}
}
}
// the server response is in [response.data]
return response.data;
}
}
// class export
export default Dao;
Das Projekt [vuejs-10] verwendet in den Zeilen 18–30 ausschließlich die asynchrone Methode [initSession]. Beachten Sie, dass die Klasse [Dao] in Zeile 10 mit einem [axios]-Parameter instanziiert wird, der vom aufrufenden Code initialisiert wird. In diesem Fall ist der aufrufende Code das Skript [./main.js].
12.3. Das [pluginDao]-Plugin
Das [pluginDao]-Plugin sieht wie folgt aus:
export default {
install(Vue, dao) {
// ajoute une propriété [$dao] à la classe Vue
Object.defineProperty(Vue.prototype, '$dao', {
// lorsque Vue.$dao est référencé, on rend le 2ième paramètre [dao]
get: () => dao,
})
}
}
Wenn wir uns an die Erklärung für das [event-bus]-Plugin erinnern, sehen wir, dass das [pluginDao]-Plugin eine neue Eigenschaft namens [$dao] in der [Vue]-Klasse/Funktion erstellt. Diese Eigenschaft wird (wie wir zeigen werden) als Wert das vom Skript [./Dao] exportierte Objekt haben, d. h. die vorherige [Dao]-Klasse.
12.4. Das Hauptskript [main.js]
Der Code für das Hauptskript [main.js] lautet wie folgt:
// 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'
// couche [dao]
import Dao from './Dao';
// configuration axios
axios.defaults.timeout = 2000;
axios.defaults.baseURL = 'http://localhost/php7/scripts-web/impots/version-14';
axios.defaults.withCredentials = true;
// instanciation couche [dao]
const dao = new Dao(axios);
// plugin [dao]
import pluginDao from './plugins/dao'
Vue.use(pluginDao, dao)
// configuration
Vue.config.productionTip = false
// instanciation projet [App]
new Vue({
render: h => h(App),
}).$mount('#app')
Das Skript [main.js]:
- instanziiert die [dao]-Schicht in den Zeilen 14–21;
- bindet das Plugin [pluginDao] in den Zeilen 24–25 ein;
- Zeile 15: Die Klasse [Dao] wird importiert;
- Zeilen 17–18: Das [axios]-Objekt, das HTTP-Anfragen verarbeitet, wird konfiguriert. Dieses Objekt wird in Zeile 4 importiert;
- Zeile 17: definiert ein [timeout] von 2 Sekunden;
- Zeile 18: die URL des Steuerberechnungsservers;
- Zeile 19: zum Aktivieren des Cookie-Austauschs mit dem Server;
- Zeilen 24–25: Verwendung des Plugins [pluginDao]
- Zeile 24: Import des Plugins;
- Zeile 25: Integration des Plugins. Wir sehen, dass der zweite Parameter der Methode [Vue.use] die Referenz auf die in Zeile 21 definierte [dao]-Schicht ist. Deshalb verweist die Eigenschaft [Vue.$dao] in allen Instanzen der Klasse/Funktion [Vue], d. h. in allen [Vue.js]-Komponenten, auf die [dao]-Schicht;
12.5. Die Hauptansicht [App.vue]
Der Code für die Hauptansicht [App] lautet wie folgt:
<template>
<div class="container">
<b-card>
<!-- message -->
<b-alert show variant="success" align="center">
<h4>[vuejs-10] : plugin [dao], requêtes HTTP asynchrones</h4>
</b-alert>
<!-- composant faisant une requête asynchrone au serveur de calcul d'impôt-->
<Component1 @error="doSomethingWithError" @endWaiting="endWaiting" @beginWaiting="beginWaiting" />
<!-- affichage d'une éventuelle erreur -->
<b-alert show
variant="danger"
v-if="showError">Evénement [error] intercepté par [App]. Valeur reçue = {{error}}</b-alert>
<!-- message d'attente avec un 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",
// état du composant
data() {
return {
// contrôle le spinner d'attente
showWaiting: false,
// contrôle l'affichage de l'erreur
showError: false,
// l'erreur interceptée
error: {}
};
},
// composants utilisés
components: {
Component1
},
// méthodes de gestion des évts
methods: {
// début attente
beginWaiting() {
// on affiche l'attente
this.showWaiting = true;
// on cache le msg d'erreur
this.showError = false;
},
// fin attente
endWaiting() {
// on cache l'attente
this.showWaiting = false;
},
// gestion d'erreur
doSomethingWithError(error) {
// on note qu'il y a eu erreur
this.error = error;
// on affiche le msg d'erreur
this.showError = true;
}
}
};
</script>
Kommentare
- Zeile 9: [Component1] ist die Komponente, die die asynchrone HTTP-Anfrage stellt. Sie kann drei Ereignisse auslösen:
- [beginWaiting]: Die Anfrage wird gleich gestellt. Dem Benutzer muss eine Wartemeldung angezeigt werden;
- [endWaiting]: Die Anfrage ist abgeschlossen. Das Warten muss beendet werden;
- [error]: Die Anfrage ist fehlgeschlagen. Es muss eine Fehlermeldung angezeigt werden;
- Zeilen 10–13: Die Benachrichtigung, die etwaige Fehlermeldungen anzeigt. Sie wird durch den booleschen Wert [showError] in Zeile 33 gesteuert. Sie zeigt den Fehler in Zeile 35 an;
- Zeilen 14–18: Die Benachrichtigung, die die Wartemeldung mit einem Lade-Symbol anzeigt. Sie wird durch die boolesche Variable [showWaiting] in Zeile 47 gesteuert;
- Zeilen 45–50: [beginWaiting] ist die Methode, die beim Empfang des [beginWaiting]-Ereignisses ausgeführt wird. Sie zeigt die Wartemeldung an (Zeile 47) und blendet die Fehlermeldung aus (Zeile 49), falls diese noch aus einem vorherigen Vorgang sichtbar ist;
- Zeilen 52–55: [endWaiting] ist die Methode, die beim Empfang des [endWaiting]-Ereignisses ausgeführt wird. Sie blendet die Wartemeldung aus (Zeile 54);
- Zeilen 57–62: [doSomethingWithError] ist die Methode, die beim Empfang des [error]-Ereignisses ausgeführt wird. Sie protokolliert den empfangenen Fehler (Zeile 59) und zeigt die Fehlermeldung an (Zeile 61);
12.6. Die Komponente [Component1]
Der Code für die Komponente [Component1] lautet wie folgt:
<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",
// component status
data() {
return {
showMsg: false
};
},
// event management methods
methods: {
// processing data received from the server
doSomethingWithData(data) {
// record the data received
this.data = data;
// we display it
this.showMsg = true;
}
},
// the component has just been created
created() {
// initialize the session with the server - asynchronous request
// we use the promise rendered by the [dao] layer methods
// we signal the start of the operation
this.$emit("beginWaiting");
// asynchronous operation is launched
this.$dao
// initialize a jSON session with the tax calculation server
.initSession()
// method that processes the data received in the event of success
.then(data => {
// we process the data received
this.doSomethingWithData(data);
})
// error handling method in case of error
.catch(error => {
// the error is traced back to the parent component
this.$emit("error", error.message);
}).finally(() => {
// end of wait
this.$emit("endWaiting");
})
}
};
</script>
Kommentare
- Zeilen 4–6: Die Komponente besteht aus einer einzigen Meldung, die den vom Steuerberechnungsserver zurückgegebenen Wert anzeigt, jedoch nur, wenn die HTTP-Anfrage erfolgreich ist. Diese Meldung wird durch die boolesche Variable [showMsg] in Zeile 17 gesteuert;
- Zeilen 31–53: Die HTTP-Anfrage wird gestellt, sobald die Komponente erstellt wird. Daher befindet sich der entsprechende Code in der Methode [created] in Zeile 31;
- Zeile 35: Die übergeordnete Komponente wird darüber informiert, dass die asynchrone Anfrage in Kürze gestartet wird;
- Zeilen 37–39: Die Methode [this.$dao.initSession] wird ausgeführt. Sie initialisiert eine JSON-Sitzung mit dem Steuerberechnungsserver. Das unmittelbare Ergebnis dieser Methode ist ein [Promise];
- Zeilen 41–44: Dieser Code wird ausgeführt, wenn der Server sein Ergebnis ohne Fehler zurückgibt. Das Ergebnis des Servers befindet sich in [data]. In Zeile 43 rufen wir die Methode [doSomethingWithData] auf, um dieses Ergebnis zu verarbeiten;
- Zeilen 46–49: Dieser Code wird ausgeführt, wenn bei der Ausführung der Anfrage ein Fehler auftritt. In Zeile 48 wird die übergeordnete Komponente darüber informiert, dass ein Fehler aufgetreten ist, und die Fehlermeldung [error.message] wird an sie übergeben;
- Zeilen 49–52: Dieser Code wird in jedem Fall ausgeführt. Wir benachrichtigen die übergeordnete Komponente, dass die HTTP-Anfrage abgeschlossen ist;
- Zeilen 23–28: Die Methode [doSomethingWithData] ist für die Verarbeitung der vom Server gesendeten Daten [data] zuständig. In Zeile 25 werden diese Daten gespeichert und in Zeile 27 angezeigt;
12.7. Ausführen des Projekts

Wenn der Steuerberechnungsserver beim Starten des Projekts nicht läuft, ergibt sich folgendes Ergebnis:

Starten wir den [Laragon]-Server (siehe https://tahe.developpez.com/tutoriels-cours/php7) und laden wir die obige Seite neu. Das Ergebnis sieht dann wie folgt aus:

Hinweis: Wir verwenden Version 14 des Steuerberechnungsservers, der unter https://tahe.developpez.com/tutoriels-cours/php7 definiert ist.