Ref, který se sám ukládá

Ukládání do localStorage potřebuje pokaždé stejné řádky: při vytvoření refu přečíst, co je uložené, a pomocí watch to při každé změně uložit. S composable je napíšete jen jednou:

import { ref, watch } from "vue";

export function useLocalStorage(klic, vychozi) {
    const ulozene = localStorage.getItem(klic);
    const hodnota = ref(ulozene === null ? vychozi : JSON.parse(ulozene));

    watch(
        hodnota,
        (novaHodnota) => {
            localStorage.setItem(klic, JSON.stringify(novaHodnota));
        },
        { deep: true },
    );

    return hodnota;
}

Každá hodnota, která má zůstat, pak zabere jeden řádek:

const jmeno = useLocalStorage("jmeno", "");
const objednavka = useLocalStorage("objednavka", []);

Jak to funguje:

  • Composable má dva parametry: klic, název, pod kterým ukládá, a vychozi, hodnotu, se kterou se začíná, když ještě nic uložené není. Díky nim stejná funkce uloží jméno pod "jmeno" a objednávku pod "objednavka".
  • Vrací jediný ref, žádný objekt, a tak není co vytahovat: po const jmeno = useLocalStorage("jmeno", ""); je jmeno ref, připravený pro v-model nebo {{ jmeno }}.
  • watch uvnitř patří k danému volání: každé volání sleduje svůj vlastní ref a ukládá ho pod svým klíčem. { deep: true } tam je, aby se uložilo i push() do pole, jak to znáte z lekce Vypočítané hodnoty a sledování.
  • JSON.stringify() a JSON.parse() fungují i pro text, čísla, true a false, takže composable uloží cokoli.

Komponenta z toho nic nevidí. S jmeno a objednavka pracuje jako s jakýmkoli jiným refem a ty se ukládají samy.

Pokyny

  1. V useLocalStorage.js napište useLocalStorage(klic, vychozi) jako v ukázce. V App.vue ji importujte a použijte pro jméno: const jmeno = useLocalStorage("jmeno", "");. Vyzkoušejte to: napište své jméno a klikněte na Spustit. Jméno zůstane.

  2. Použijte ji i pro objednávku, s klíčem objednavka a prázdným polem na začátek. Něco si objednejte a klikněte na Spustit: objednávka zůstane. A Vymazat objednávku ji vymaže natrvalo.