Die Speisekarte laden
Die Speisekarte des Cafés ändert sich mit den Jahreszeiten, also gehört sie nicht in den Code. Sie steht in einer Datei, menue.json, und die App lädt sie, so wie du im JavaScript-Kurs Dateien mit fetch() geladen hast. In einer Komponente ist onMounted der richtige Ort dafür:
<script setup>
import { onMounted, ref } from "vue";
const menue = ref([]);
onMounted(async () => {
const antwort = await fetch("menue.json");
menue.value = await antwort.json();
});
</script>Das passiert dabei:
- Vue erstellt die Komponente:
menueist ein leeres Array. - Vue hängt sie ein: Die Seite zeigt die Komponente mit einer leeren Liste, und Vue ruft die Funktion auf, die du
onMountedgegeben hast. Sie fragt nachmenue.jsonund wartet. - Einen Moment später kommt die Antwort.
menue.value = …legt die Speisekarte in den Ref, und Vue aktualisiert die Seite, wie nach jeder anderen Änderung von State.
Die Funktion ist async, damit sie await benutzen kann, wie die Funktionen, die im JavaScript-Kurs Daten geladen haben. async steht vor den Klammern der Pfeilfunktion.
Warum schreibst du die zwei Zeilen mit await nicht einfach oben ins <script setup>, zum übrigen Code? So beginnt diese Übung, und die Seite zeigt nichts, nicht einmal die Überschrift. Die Konsole zeigt:
[Vue warn]: Component <App>: setup function returned a promise, but no <Suspense> boundary was found in the parent component tree. A component with async setup() must be nested in a <Suspense> in order to be rendered.
at <App>Ein await ganz oben lässt die ganze Komponente warten: Vue kann sie erst fertig erstellen, wenn die Daten da sind, und zeigt eine solche Komponente nur innerhalb von <Suspense>, einem Teil von Vue, der noch experimentell ist und den dieser Kurs nicht benutzt. Schreibe also nie await ganz oben ins <script setup>. Lade Daten in onMounted und lass die Seite in der Zwischenzeit etwas zeigen.
Zum Beispiel Wird geladen…: Bei einer langsamen Verbindung kann es einige Sekunden dauern, bis die Daten ankommen. Ein Ref, der true ist, bis die Daten da sind, sagt der Vorlage, was sie zeigen soll.
So schreibst du es:
Anweisungen
- 1
Lade die Speisekarte in
onMounted: Importiere es nebenrefund verschiebe die zwei Zeilen mitawaitinonMounted(async () => { … });. Die Seite zeigt die Überschrift und einen Moment später die Speisekarte. - 2
Zeige, während die Speisekarte lädt,
<p>Wird geladen…</p>anstelle der Liste. Füge einen Reflaedthinzu, der mittruebeginnt, setze ihn inonMountedauffalse, sobald die Speisekarte da ist, und zeige den Absatz mitv-if="laedt"und die Liste mitv-else.