Vaše první composable

Komponenty rostou. V lekci Životní cyklus a data zabralo načtení nabídky tři refy a onMounted a každá další komponenta, která něco načítá, by potřebovala stejné řádky znovu. Takové řádky stačí napsat jednou, do funkce composable (zkráceně jen composable, v množném čísle composables). Je to funkce, která používá ref, computed, watch nebo funkce životního cyklu z Vue a vrací, co komponenta potřebuje. Názvy composables začínají na use, aby se poznaly: usePocitadlo, useLocalStorage, useNacitani.

Tady je počítadlo jako composable. Má vlastní soubor, usePocitadlo.js:

import { ref } from "vue";

export function usePocitadlo(zacatek) {
    const pocet = ref(zacatek);

    function pridej() {
        pocet.value++;
    }

    return { pocet, pridej };
}

A tady je komponenta, která ji používá:

<script setup>
import { usePocitadlo } from "./usePocitadlo.js";

const { pocet, pridej } = usePocitadlo(0);
</script>

<template>
    <p>Šálků kávy dnes: {{ pocet }}</p>
    <button @click="pridej">+1 šálek</button>
</template>

Co je nové:

  • Composable je v souboru .js, ne .vue: nemá šablonu ani styly, jen JavaScript. Z "vue" si importuje, co používá.
  • export před function je pojmenovaný export, jak ho znáte z lekce Komponenty, kde byl před const. Composable se proto importuje pod svým názvem ve složených závorkách, import { usePocitadlo } from "./usePocitadlo.js";, stejně jako ref z "vue".
  • Komponenta composable zavolá nahoře v <script setup>, stejně jako volá ref(). Composable v tu chvíli vytvoří ref a funkci, vrátí je v objektu a destrukturování je z něj vytáhne: const { pocet, pridej } = usePocitadlo(0);.
  • Od té chvíle pocet a pridej fungují, jako by byly napsané přímo v komponentě: pocet je ref, který ukáže {{ pocet }}, a pridej je funkce pro @click.

Každé volání vytvoří nový ref: dvě komponenty, které zavolají usePocitadlo(), mají každá svůj vlastní počet. Zavolat composable je jako zkopírovat její řádky do komponenty, jenže napsané jsou jen jednou.

Typické chyby:

  • import usePocitadlo from "./usePocitadlo.js"; bez složených závorek: tak se importuje výchozí export souboru (default), který soubor nemá. Stránka zůstane prázdná a v konzoli je TypeError.
  • Chybějící return: funkce pak vrátí undefined a destrukturování skončí chybou TypeError, která začíná Cannot destructure property 'pocet'.

Pokyny

  1. Přesuňte počítadlo do composable. V usePocitadlo.js napište usePocitadlo(zacatek) jako v ukázce. V App.vue ji importujte a ref i funkci nahraďte řádkem const { pocet, pridej } = usePocitadlo(0);. Stránka funguje jako předtím.

  2. Přidejte do composable funkci vynuluj(), která pocet vrátí na zacatek, tedy číslo, kterým počítadlo začalo, a vraťte ji taky. V App.vue ji vytáhněte spolu s ostatními a za +1 šálek přidejte tlačítko Vynulovat, které ji zavolá.