Unterschiede
Hier werden die Unterschiede zwischen zwei Versionen angezeigt.
| Beide Seiten der vorigen Revision Vorhergehende Überarbeitung Nächste Überarbeitung | Vorhergehende Überarbeitung | ||
| de:modul:m291:learningunits:lu12:theorie:a_fetching_data [2026/05/18 09:35] – gelöscht - Externe Bearbeitung (Unbekanntes Datum) 127.0.0.1 | de:modul:m291:learningunits:lu12:theorie:a_fetching_data [2026/05/18 09:35] (aktuell) – gkoch | ||
|---|---|---|---|
| Zeile 1: | Zeile 1: | ||
| + | ====== LU12a – Daten von einer API laden ====== | ||
| + | ===== Was ist eine API? ===== | ||
| + | |||
| + | Bisher lagen alle FAQ-Daten direkt im Code – hartcodiert in einem Array. In echten Webprojekten kommen Inhalte aber fast immer von **aussen**: aus einer Datenbank, einem CMS oder einer externen Quelle. | ||
| + | |||
| + | Der Weg dorthin führt über eine **API** (Application Programming Interface) – eine Schnittstelle, | ||
| + | |||
| + | {{: | ||
| + | |||
| + | <WRAP box center round 80%> | ||
| + | ^ Wir (Browser / Vue App) ^ ^ API / Server ^ | ||
| + | | «Gib mir alle FAQs» | →→ GET Request →→ | Datenbank | | ||
| + | | Bekommt JSON-Daten zurück | ←← Response ←← | Schickt Daten zurück | | ||
| + | </ | ||
| + | |||
| + | |||
| + | ===== Das Problem: Netzwerkanfragen brauchen Zeit ===== | ||
| + | |||
| + | Ein normaler JavaScript-Funktionsaufruf ist sofort fertig. Eine Anfrage ans Netzwerk dauert dagegen eine Weile – die App weiss nicht, wie lange. | ||
| + | |||
| + | Wenn JavaScript einfach **wartet**, bis die Daten da sind, friert die ganze Seite ein. Buttons reagieren nicht mehr, nichts bewegt sich. Das wäre eine schlechte User Experience. | ||
| + | |||
| + | Die Lösung: **asynchrones JavaScript** – der Browser wartet auf die Daten, aber der Rest der App läuft währenddessen weiter. | ||
| + | |||
| + | {{: | ||
| + | |||
| + | |||
| + | ===== async / await ===== | ||
| + | |||
| + | Mit den Schlüsselwörtern '' | ||
| + | |||
| + | <WRAP box center round 80%> | ||
| + | <code javascript> | ||
| + | async function fetchFaqs() { | ||
| + | const response = await fetch(' | ||
| + | const data = await response.json(); | ||
| + | console.log(data); | ||
| + | } | ||
| + | </ | ||
| + | </ | ||
| + | <WRAP box center round 80%> | ||
| + | ^ Schlüsselwort ^ Bedeutung ^ | ||
| + | | '' | ||
| + | | '' | ||
| + | | '' | ||
| + | | '' | ||
| + | </ | ||
| + | <WRAP tip round> | ||
| + | **Warum zwei '' | ||
| + | </ | ||
| + | |||
| + | ===== try / catch / finally ===== | ||
| + | |||
| + | Was passiert, wenn die API nicht erreichbar ist oder einen Fehler zurückgibt? | ||
| + | |||
| + | <WRAP box center round 80%> | ||
| + | <code javascript> | ||
| + | try { | ||
| + | // Code, der einen Fehler verursachen könnte | ||
| + | const response = await fetch(' | ||
| + | } catch (err) { | ||
| + | // Wird ausgeführt, | ||
| + | console.log(' | ||
| + | } finally { | ||
| + | // Wird IMMER ausgeführt – egal ob Erfolg oder Fehler | ||
| + | isLoading.value = false; | ||
| + | } | ||
| + | </ | ||
| + | </ | ||
| + | |||
| + | <WRAP box center round 80%> | ||
| + | ^ Block ^ Wann? ^ | ||
| + | | '' | ||
| + | | '' | ||
| + | | '' | ||
| + | </ | ||
| + | |||
| + | ===== onMounted ===== | ||
| + | |||
| + | Wann soll die Funktion '' | ||
| + | |||
| + | <WRAP box center round 80%> | ||
| + | <code javascript> | ||
| + | import { ref, onMounted } from ' | ||
| + | |||
| + | onMounted(fetchFaqs); | ||
| + | </ | ||
| + | </ | ||
| + | |||
| + | '' | ||
| + | |||
| + | |||
| + | ===== v-if / v-else-if / v-else ===== | ||
| + | |||
| + | Beim Laden von Daten gibt es immer drei mögliche Zustände, die wir im Template abbilden: | ||
| + | |||
| + | <WRAP box center round 80%> | ||
| + | <code html> | ||
| + | <div v-if=" | ||
| + | |||
| + | <div v-else-if=" | ||
| + | |||
| + | <div v-else> | ||
| + | <!-- Daten sind da: AccordionItems anzeigen --> | ||
| + | </ | ||
| + | </ | ||
| + | </ | ||
| + | |||
| + | <WRAP round box 80% center> | ||
| + | ^ Direktive ^ Wann wird dieses Element angezeigt? ^ | ||
| + | | '' | ||
| + | | '' | ||
| + | | '' | ||
| + | |||
| + | Diese drei Blöcke schliessen sich gegenseitig aus – Vue zeigt immer nur einen davon an. | ||
| + | </ | ||
| + | |||
| + | ===== Der vollständige Ablauf ===== | ||
| + | |||
| + | <WRAP box center round 80%> | ||
| + | < | ||
| + | 1. Komponente wird gerendert (onMounted) | ||
| + | ↓ | ||
| + | 2. fetchFaqs() wird aufgerufen | ||
| + | ↓ | ||
| + | 3. isLoading = true → «Daten werden geladen...» erscheint | ||
| + | ↓ | ||
| + | 4. fetch() sendet GET-Request an MockAPI | ||
| + | ↓ | ||
| + | 5. Antwort kommt zurück | ||
| + | ↓ | ||
| + | 6. faqItems.value = data → Vue rendert die AccordionItems | ||
| + | ↓ | ||
| + | 7. isLoading = false → Ladeanzeige verschwindet | ||
| + | </ | ||
| + | </ | ||