Das Vue-Framework für JavaScript ist für die Erstellung von Benutzeroberflächen und Single-Page-Anwendungen (SPAs) sehr beliebt geworden. Um sicherzustellen, dass deine großen Anwendungen optimal funktionieren, musst du das Zustandsmanagement beherrschen – den Prozess der Verwaltung und Zentralisierung der reaktiven Daten (Zustände) einer Anwendung über mehrere Komponenten hinweg.

In Vue basiert das Zustandsmanagement seit langem auf Vuex, einer Bibliothek mit einem zentralen Speicher für alle Komponenten einer Anwendung. Die jüngsten Fortschritte im Vue-Ökosystem haben jedoch den Nachfolger von Vuex, Pinia, hervorgebracht.

Pinia bietet einen schlankeren, modulareren und intuitiveren Verwaltungsansatz. Es lässt sich nahtlos in das Reaktivitätssystem und die Composition API von Vue integrieren und macht es Entwicklern leicht, gemeinsame Zustände auf skalierbare und wartbare Weise zu verwalten und darauf zuzugreifen.

Die Ausgangslage: Pinia vs. Vuex

Als Standardbibliothek für die Zustandsverwaltung in Vue-Anwendungen bot Vuex einen zentralen Speicher für alle Komponenten einer Anwendung. Mit der Weiterentwicklung von Vue stellt Pinia jedoch eine modernere Lösung dar. Wir wollen herausfinden, wie sie sich von Vuex unterscheidet.

  • API-Unterschiede – Die Composition-API von Pinia bietet eine grundlegendere und intuitivere API als Vuex, die es einfacher macht, den Zustand der Anwendung zu verwalten. Außerdem ähnelt ihre Struktur stark der Options-API von Vue, die den meisten Vue-Entwicklern vertraut ist.
  • Typing-Unterstützung – In der Vergangenheit hatten viele Vue-Entwickler mit der begrenzten Typ-Unterstützung von Vuex zu kämpfen. Im Gegensatz dazu ist Pinia eine vollständig typisierte Zustandsmanagement-Bibliothek, die diese Bedenken ausräumt. Ihre Typsicherheit hilft, potenzielle Laufzeitfehler zu vermeiden, trägt zur Lesbarkeit des Codes bei und ermöglicht eine reibungslosere Skalierung.
  • Reaktivitätssystem – Beide Bibliotheken nutzen das Reaktivitätssystem von Vue, aber der Ansatz von Pinia ist enger an die Composition API von Vue 3 angelehnt. Die Reaktivitäts-API ist zwar leistungsstark, aber die Verwaltung komplexer Zustände in großen Anwendungen kann eine Herausforderung sein. Zum Glück erleichtert die einfache und flexible Architektur von Pinia die Verwaltung von Zuständen in deinen Vue 3-Anwendungen. Mit dem Store-Pattern von Pinia kannst du einen Store definieren, der einen bestimmten Teil des Anwendungsstatus verwaltet, seine Organisation vereinfacht und ihn mit anderen Komponenten teilt.
  • Geringes Gewicht – Mit nur 1 KB fügt sich Pinia nahtlos in deine Entwicklungsumgebung ein und kann durch sein geringes Gewicht die Leistung und Ladezeiten deiner Anwendung verbessern.

So richtest du ein Vue-Projekt mit Pinia ein

Um Pinia in ein Vue-Projekt zu integrieren, initialisiere dein Projekt mit Vue CLI oder Vite. Nach der Projektinitialisierung kannst du Pinia über npm oder yarn als Abhängigkeit installieren.

  1. Erstelle ein neues Vue-Projekt mit Vue CLI oder Vite. Befolge dann die Anweisungen, um dein Projekt einzurichten.
    // Using Vue CLI
    vue create my-vue-ap
    // Using Vite
    npm create vite@latest my-vue-app -- --template vue
  2. Wechsle dein Verzeichnis in den neu erstellten Projektordner:
    cd my-vue-app
  3. Installiere Pinia als eine Abhängigkeit in deinem Projekt.
    // Using npm
    npm install pinia
    // Using yarn
    yarn add pinia
  4. Importiere Pinia in deiner Haupteingabedatei (normalerweise main.js oder main.ts) und befehle Vue es zu verwenden:
    import { createApp } from 'vue';
    import { createPinia } from 'pinia';
    import App from './App.vue';
    
    const app = createApp(App);
    
    app.use(createPinia());
    app.mount('#app');

    Wenn du Pinia in deinem Vue-Projekt installiert und eingerichtet hast, kannst du Stores für die Zustandsverwaltung definieren und verwenden.

Wie man einen Store in Pinia erstellt

Der Store ist das Rückgrat der Zustandsverwaltung in deiner Vue-Anwendung, die mit Pinia betrieben wird. Er hilft dir, anwendungsweite Daten auf kohärente und koordinierte Weise zu verwalten. Im Store definierst, speicherst und verwaltest du die Daten, die von den verschiedenen Komponenten deiner Anwendung gemeinsam genutzt werden sollen.

Diese Zentralisierung ist wichtig, denn sie strukturiert und organisiert die Zustandsänderungen deiner Anwendung und macht den Datenfluss vorhersehbarer und einfacher zu debuggen.

Außerdem kann ein Store in Pinia mehr als nur den Status speichern: Mit den integrierten Funktionen von Pinia kannst du den Status über Aktionen aktualisieren und abgeleitete Status über Getter berechnen. Diese eingebauten Funktionen tragen zu einer effizienteren und besser wartbaren Codebasis bei.

Das folgende Beispiel zeigt, wie du einen einfachen Pinia-Store in der Datei src/store.js deines Projekts erstellst.

import { defineStore } from 'pinia';
export const useStore = defineStore('main', {
    state: () => ({
        count: 0,
    }),
    actions: {
        increment() {
            this.count++;
        },
    },
    getters: {
        doubleCount: (state) => state.count * 2,
    },
});

Wie man auf den Store-Status in Komponenten zugreift

Im Vergleich zu Vuex ist der Ansatz von Pinia für den Zugriff auf und die Verwaltung von Zuständen intuitiver, vor allem wenn du mit der Composition API von Vue 3 vertraut bist. Bei dieser API handelt es sich um eine Reihe von Funktionen, mit denen du reaktive und komponierbare Logik in deine Komponenten einbauen kannst.

Betrachte den folgenden Code.

<template>
	<div>{{ store.count }}</div>
</template>

<script>>
import { useStore } from './store';

export default {
	setup() {
	const store = useStore();
		return { store };
	},
}
</script>

Im obigen Codeausschnitt enthält der <template> Tag das definierte HTML-Markup deiner Komponente. Um den Wert der Eigenschaft count aus dem Pinia-Speicher anzuzeigen, verwendest du die Datenbindungssyntax von Vue, ausgedrückt als {{ count }}.

Die Funktion useStore ermöglicht den Zugriff auf den Pinia-Speicher, also importierst du ihn mit import { useStore } from './store'; aus store.js.

Die Funktion setup ist ein Feature der Composition API von Vue 3 und definiert den reaktiven Zustand und die Logik deiner Komponente. Innerhalb der Funktion rufst du dann useStore() auf, um auf den Pinia-Store zuzugreifen.

Als Nächstes greift const count = store.count auf die Eigenschaft count des Stores zu und macht sie in der Komponente verfügbar.

Schließlich gibt setup die count zurück, damit das Template sie rendern kann. Das Reaktivitätssystem von Vue bedeutet, dass das Template deiner Komponente den Wert von count aktualisiert, sobald er sich im Store ändert.

Unten siehst du einen Screenshot der Ausgabe.

Screenshot der Pinia Store Demo-Vorlage, die in einem Browser geladen wurde
Screenshot der Pinia Store Demo-Vorlage, die in einem Browser geladen wurde

Dieses Beispiel veranschaulicht die Vorteile von Pinia:

  • Einfachheit – Pinia ermöglicht den direkten Zugriff auf den Zustand des Stores ohne Mapping-Funktionen. Im Gegensatz dazu benötigt Vuex mapState (oder ähnliche Helfer), um den gleichen Zugriff zu erreichen.
  • Direkter Speicherzugriff – Mit Pinia kannst du direkt auf Statuseigenschaften (wie store.count) zugreifen, was deinen Code lesbarer und verständlicher macht. In Vuex sind dagegen oft Getter erforderlich, um selbst auf grundlegende Eigenschaften zuzugreifen, was die Komplexität erhöht und die Lesbarkeit beeinträchtigt.
  • Kompatibilität mit der Composition API – Wie die Setup-Methode zeigt, passt Pinia besonders gut zur modernen Vue-Entwicklung und sorgt für eine einheitlichere Codierung.

Wie du den Status mit Pinia änderst

In Pinia änderst du den Zustand eines Ladens mit Aktionen, die flexibler sind als Vuex-Mutationen. Betrachte den folgenden Funktionsaufruf, der die Eigenschaft count erhöht:

store.increment(); // Increments the count

Das Äquivalent in Vuex hingegen besteht darin, neben mindestens einer Aktion auch eine Mutation zu definieren:

mutations: {
	increment(state) {
	state.count++;
	},
},
actions: {
	increment({ commit }) {
	commit('increment');
	},
}

Die Pinia-Aktion und ihr Äquivalent in Vuex verdeutlichen einen entscheidenden Unterschied in der Komplexität des Codes der Bibliotheken. Lass uns diese Unterschiede genauer untersuchen:

  • Direkte versus indirekte Zustandsänderung – Wie die Aktion increment zeigt, ändern Pinia-Aktionen den Zustand des Stores direkt. In Vuex kannst du den Zustand nur mit Mutationen ändern, die du mit Aktionen übertragen musst. Diese Prozesstrennung stellt sicher, dass deine Zustandsänderungen nachvollziehbar sind, aber sie ist komplexer und starrer als vergleichbare Pinia-Aktionen.
  • Asynchrone versus synchrone Operationen – Während Vuex-Mutationen immer synchron sind und keine asynchronen Prozesse enthalten können, können Pinia-Aktionen synchronen und asynchronen Code enthalten. Daher kannst du API-Aufrufe oder andere asynchrone Operationen direkt in Aktionen ausführen, was zu einer schlankeren und übersichtlicheren Codebasis führt.
  • Vereinfachte Syntax – In Vuex müssen oft Mutationen definiert und Aktionen aufgerufen werden, um sie zu übertragen. Mit Pinia ist das nicht mehr nötig. Die Möglichkeit, den Zustand innerhalb von Aktionen zu verändern, reduziert den Boilerplate-Code und macht deinen bestehenden Code übersichtlicher. In Vuex müssen für grundlegende Zustandsaktualisierungen eine Aktion und eine Mutation definiert werden, selbst wenn die Aktion nur die Mutation festschreibt.

Der Übergang von Vuex zu Pinia

Der Umstieg auf Pinia kann zahlreiche Vorteile in Bezug auf Einfachheit, Flexibilität und Wartbarkeit bieten, erfordert aber eine sorgfältige Planung und Überlegung, um eine erfolgreiche Implementierung zu gewährleisten.

Bevor du umsteigst, solltest du Folgendes beachten:

  1. Mache dich mit den Unterschieden zwischen der Architektur von Pinia und Vuex, den Mustern für die Zustandsverwaltung und den APIs vertraut. Das Verständnis dieser Unterschiede ist entscheidend, um deinen Code effektiv zu refaktorisieren und die Funktionen von Pinia voll auszuschöpfen.
  2. Analysiere deinen Vuex-Zustand, deine Actions, Mutationen und Getter und passe sie an die Struktur von Pinia an. Denke daran, dass du in Pinia den Zustand als Funktion definierst. Du kannst Zustände direkt mit Actions verändern und Getters reibungsloser implementieren.
  3. Plane, wie du die Module deines Vuex-Lagers umwandeln kannst. Pinia verwendet zwar keine Module wie Vuex, aber du kannst deine Stores trotzdem so strukturieren, dass sie ähnliche Zwecke erfüllen.
  4. Nutze die verbesserte TypeScript-Unterstützung von Pinia. Wenn dein Projekt TypeScript verwendet, solltest du Pinias verbesserte Typinferenz- und Typisierungsfunktionen in Betracht ziehen, um die Typsicherheit und die Erfahrung der Entwickler zu verbessern.
  5. Überarbeite deine Teststrategien, um die Änderungen in der Zustandsverwaltung zu berücksichtigen. Dies kann bedeuten, dass du die Art und Weise, wie du Speicher oder Aktionen in deinen Unit- und Integrationstests simulierst, aktualisierst.
  6. Überlege, wie sich die Umstellung auf die Struktur und Organisation deines Projekts auswirkt. Berücksichtige Faktoren wie Namenskonventionen und die Art und Weise, wie du Stores komponentenübergreifend importierst und verwendest.
  7. Stelle die Kompatibilität mit anderen Bibliotheken sicher. Überprüfe, ob die Umstellung Auswirkungen auf erforderliche Aktualisierungen oder Änderungen von Abhängigkeiten haben könnte.
  8. Beurteile alle Leistungsänderungen. Pinia ist in der Regel schlanker als Vuex, aber überwache die Leistung deiner Anwendung während und nach der Umstellung, um sicherzustellen, dass es keine Probleme gibt.

Die Umstellung eines Stores von Vuex auf Pinia erfordert mehrere Schritte, um die Unterschiede in den Strukturen und APIs zu berücksichtigen. Betrachte den Pinia-Store von vorhin.

Derselbe Store sieht in einer Vuex store.js-Datei wie folgt aus.

import Vue from 'vue';
import Vuex from 'vuex';
Vue.use(Vuex);

export default new Vuex.Store({
    state: {
        count: 0,
    },
    mutations: {
        increment(state) {
            state.count++;
        },
    },
    actions: {
        increment(context) {
            context.commit('increment');
        },
    },
    getters: {
        doubleCount(state) {
            return state.count * 2;
        },
    },
});

Wie der vorherige Pinia-Store enthält auch dieses Vuex-Beispiel ein state -Objekt mit einer einzigen count -Eigenschaft, die auf 0 initialisiert ist.

Das mutations Objekt enthält Methoden, um den Zustand direkt zu verändern, während die Methoden des actions Objekts die increment Veränderung festschreiben.

Dann enthält das getters Objekt die Methode doubleCount, die den Zustand count mit 2 multipliziert und das Ergebnis zurückgibt.

Wie dieser Code zeigt, gibt es bei der Implementierung eines Stores in Pinia einige deutliche Unterschiede zu Vuex:

  • Initialisierung – Pinia benötigt keine Vue.use().
  • Struktur – In Pinia ist der Zustand eine Funktion, die ein Objekt zurückgibt, was eine bessere TypeScript-Unterstützung und Reaktivität ermöglicht.
  • Aktionen – Aktionen in Pinia sind Methoden, die den Zustand direkt verändern, ohne Mutationen zu benötigen, was den Code vereinfacht.
  • Getter – Ähnlich wie bei Vuex werden Getter in Pinia innerhalb der Store-Definition definiert und können direkt auf den Status zugreifen.

Wie man den Store in Komponenten verwendet

Mit Vuex könntest du den Store wie folgt verwenden:

<template>
	<div>{{ doubleCount }}</div>
	<button @click="increment">Increment</button>
</template>

<script>
import { mapGetters, mapActions } from 'vuex';

export default {
	computed: {
	...mapGetters(['doubleCount']),
	},
	methods: {
	...mapActions(['increment']),
	},
};
</script>

Für Pinia sieht die Verwendung so aus:

<template>
	<div>{{ store.doubleCount }}</div>
	<button> @click="store.increment">Increment</button>
</template>

<script>>
import { useStore } from '/src/store';

export default {
	setup() {
	const store = useStore();
	return {
		store,
	};
	},
};
</script>
Screenshot der Pinia Store Demo Landing Page in verschiedenen Stufen: 0, 2, und 4.
Pinia Store-Stufen

Dieses Beispiel deckt eine einfache Konvertierung ab. Bei komplexeren Vuex-Stores, insbesondere bei solchen, die Module verwenden, würde die Konvertierung eine detailliertere Umstrukturierung erfordern, um sie an die Architektur von Pinia anzupassen.

So stellst du deine Vue-Anwendung bereit

Bevor du deine Anwendung bereitstellst, melde dich für eine kostenlose Testversion von Kinstas Anwendungs-Hosting-Dienst an. Du wirst die Anwendung mit Hilfe einer Dockerdatei bereitstellen.

Erstelle ein Dockerfile im Stammverzeichnis deines Projekts und füge die folgenden Inhalte ein:

FROM node:latest
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY ./ .
CMD ["npm", "run", "start"]

Dieser Code weist die Docker-Engine von Kinsta an, Node.js zu installieren (FROM node:latest), das Arbeitsverzeichnis zu erstellen (WORKDIR /app), die Node-Module aus der package.json-Datei zu installieren (RUN npm install) und den Start (CMD ["npm", "run", "start"]), der aufgerufen wird, wenn die Vue-App startet. Die Befehle COPY kopieren die angegebenen Dateien oder Verzeichnisse in das Arbeitsverzeichnis.

Danach musst du deinen Code zu einem bevorzugten Git-Anbieter pushen (Bitbucket, GitHub oder GitLab). Sobald dein Repo fertig ist, befolge diese Schritte, um deine Anwendung auf Kinsta bereitzustellen:

  1. Logge dich ein oder erstelle ein Konto, um dein MyKinsta-Dashboard zu sehen.
  2. Autorisiere Kinsta mit deinem Git-Anbieter.
  3. Wähle in der linken Seitenleiste Anwendung aus und klicke auf die Schaltfläche Anwendung hinzufügen.
  4. Wähle im erscheinenden Modal das Repository aus, das du bereitstellen möchtest. Wenn du mehrere Zweige hast, kannst du den gewünschten Zweig auswählen und einen Namen für deine Anwendung vergeben.
  5. Wähle einen der verfügbaren Rechenzentrumsstandorte.
  6. Wähle deine Build-Umgebung und wähle Dockerfile verwenden, um das Container-Image zu erstellen.
  7. Wenn sich deine Dockerdatei nicht im Stammverzeichnis deines Repos befindet, gib ihren Pfad mit Context an und klicke auf Weiter.
  8. Du kannst den Eintrag Startbefehl leer lassen. Kinsta verwendet npm start, um deine Anwendung zu starten.
  9. Wähle die Pod-Größe und die Anzahl der Instanzen, die für deine Anwendung am besten geeignet sind, und klicke auf Weiter.
  10. Gib deine Kreditkartendaten ein und klicke auf Anwendung erstellen.

Als Alternative zum Anwendungs-Hosting kannst du deine Vue-Anwendung auch als statische Website mit dem kostenlosen Statische-Seiten-Hosting von Kinsta bereitstellen.

Zusammenfassung

Der Übergang von Vuex zu Pinia stellt eine bedeutende Entwicklung in der Zustandsverwaltung innerhalb des Vue-Ökosystems dar. Die Einfachheit von Pinia, die verbesserte TypeScript-Unterstützung und die Anpassung an die Composition API von Vue 3 machen es zu einer überzeugenden Wahl für moderne Vue-Anwendungen.

Wenn du bereit bist, deine Vue-Anwendung bei Kinsta zu hosten, kannst du auf eine schnelle, sichere und zuverlässige Infrastruktur zugreifen. Melde dich bei Kinsta an und nutze unseren Anwendungs-Hosting-Dienst.

Jeremy Holcombe Kinsta

Content & Marketing Editor bei Kinsta, WordPress Web Developer und Content Writer. Außerhalb von WordPress genieße ich den Strand, Golf und Filme. Außerdem habe ich Probleme mit großen Menschen ;).