Geteilter State
Bisher lebten Daten, die mehrere Komponenten brauchten, in ihrem Elternteil: Es gab sie in Props nach unten, und die Kinder baten mit Ereignissen um Änderungen, wie in Ereignisse von Komponenten. Das ist der richtige Weg für ein Elternteil und seine Kinder. Aber manche Daten braucht die ganze App: die Bestellung, den angemeldeten Benutzer, den Warenkorb eines Shops. Sie durch jede Komponente dazwischen nach unten zu geben, wird lang.
Es gibt einen einfacheren Weg: Lege den Ref in ein eigenes Modul, außerhalb jeder Funktion, mit den Funktionen, die ihn ändern:
import { ref } from "vue";
export const bestellung = ref([]);
export function zurBestellungHinzufuegen(eintrag) {
const vorhanden = bestellung.value.find((posten) => posten.id === eintrag.id);
if (vorhanden) {
vorhanden.anzahl++;
} else {
bestellung.value.push({ ...eintrag, anzahl: 1 });
}
}Jede Komponente, die die Bestellung braucht, importiert, was sie benutzt:
<script setup>
import { bestellung } from "./bestellung.js";
</script>
<template>
<p>Bestellte Artikel: {{ bestellung.length }}</p>
</template>Das funktioniert, weil ein Modul nur einmal läuft. Das erste import führt bestellung.js aus und erstellt den Ref; jedes weitere import bekommt denselben Ref. Wenn also MenueEintrag.vue zurBestellungHinzufuegen() aufruft, fügt es der Bestellung etwas hinzu, die Bestellliste.vue zeigt, und Vue aktualisiert die Liste, wie nach jeder Änderung eines Refs.
Vergleiche es mit einem Composable: Dort steht ref() innerhalb der Funktion, also erstellt jeder Aufruf einen neuen Ref, und jede Komponente hat ihren eigenen. Hier steht ref() außerhalb, also gibt es nur einen, den alle Komponenten teilen. Dieselbe Zeile an einer anderen Stelle macht den Unterschied.
Halte die Funktionen, die den geteilten State ändern, neben ihm, im selben Modul, so wie zurBestellungHinzufuegen(). Dann weißt du immer, wo sich die Bestellung ändert: Wo auch immer sie sich ändert, geschieht es durch eine von ihnen.
In größeren Apps kommt geteilter State meistens in Pinia, eine Bibliothek vom Vue-Team, die auf derselben Idee beruht und Werkzeuge zum Finden von Fehlern hinzufügt. Du lernst sie nach diesem Kurs kennen.
So schreibst du es:
Anweisungen
- 1
Bringe die
Bestellen-Buttons zum Laufen. Importiere inMenueEintrag.vuezurBestellungHinzufuegenaus./bestellung.jsund rufe es mit dem Eintrag auf, wenn auf den Button geklickt wird. Importiere inBestellliste.vuebestellungaus./bestellung.jsanstelle des leeren Arrays. Bestelle zweimal einen Espresso: Die Liste zeigt2 × Espresso. - 2
Füge eine Möglichkeit hinzu, eine Zeile zu entfernen. Schreibe und exportiere in
bestellung.jsausBestellungEntfernen(id), die mitfilter()nur die Zeilen mit einer anderenidbehält. Füge inBestellliste.vuejeder Zeile einen Button×hinzu, der sie aufruft. - 3
Zeige die Summe der Bestellung in
App.vueunter der Überschrift:Gesamt: 8 €. Exportiere inbestellung.jseinen berechneten Wertsumme, derpreis * anzahlaller Zeilen mit einer Schleife addiert, und importiere ihn inApp.vue.