Načtení nabídky

Nabídka kavárny se mění podle ročních období, a tak do kódu nepatří. Je v souboru nabidka.json a aplikace si ji načte, stejně jako jste v kurzu JavaScriptu načítali soubory pomocí fetch(). V komponentě je na to místo onMounted:

<script setup>
import { onMounted, ref } from "vue";

const nabidka = ref([]);

onMounted(async () => {
    const odpoved = await fetch("nabidka.json");
    nabidka.value = await odpoved.json();
});
</script>

Co se stane:

  1. Vue komponentu vytvoří: nabidka je prázdné pole.
  2. Vue ji připojí: stránka ukáže komponentu s prázdným seznamem a Vue zavolá funkci předanou onMounted. Ta si řekne o nabidka.json a čeká.
  3. Odpověď přijde o chvíli později. nabidka.value = … vloží nabídku do refu a Vue aktualizuje stránku, stejně jako po každé jiné změně stavu.

Funkce je async, a tak v ní může být await, stejně jako ve funkcích, které načítaly data v kurzu JavaScriptu. async se píše před závorky šipkové funkce.

Proč nenapsat oba řádky s await rovnou nahoru do <script setup> k ostatnímu kódu? Tak toto cvičení začíná a stránka neukazuje nic, ani nadpis. Konzole hlásí:

[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>

await nahoře v <script setup> nechá čekat celou komponentu: Vue ji nemůže dokončit, dokud data nedorazí, a takovou komponentu ukáže jen uvnitř <Suspense>, části Vue, která je zatím experimentální a kterou tento kurz nepoužívá. Nahoru do <script setup> proto await nikdy nepište. Data načítejte v onMounted a nechte stránku mezitím něco ukázat.

Třeba Načítám…: při pomalém připojení můžou data putovat i několik sekund. Ref, který je true, dokud data nedorazí, řekne šabloně, co má ukázat.

Pokyny

  1. Načtěte nabídku v onMounted: importujte ho vedle ref a oba řádky s await přesuňte do onMounted(async () => { … });. Stránka ukáže nadpis a o chvíli později i nabídku.

  2. Během načítání ukažte místo seznamu <p>Načítám…</p>. Přidejte ref nacitani, který začíná jako true, v onMounted ho nastavte na false, jakmile je nabídka načtená, a odstavec ukažte pomocí v-if="nacitani" a seznam pomocí v-else.