Pinia im Entry-Point einbinden
Was ist Pinia – und warum ist es sinnvoll?
Pinia ist das offizielle State-Management-System für Vue 3 und der Nachfolger von Vuex.
Es dient dazu, Zustände zentral zu verwalten, also Daten, auf die mehrere Komponenten gleichzeitig zugreifen oder die sie verändern müssen – beispielsweise Benutzerinformationen, API-Daten oder UI-Status.
Anstatt Werte über Props und Events zwischen Komponenten zu verschachteln, bietet Pinia eine einfache, reaktive und typsichere Lösung.
Vorteile von Pinia:
- Offiziell vom Vue-Team entwickelt und optimal in Vue 3 integriert
- Native TypeScript-Unterstützung
- Reaktive State-Verwaltung mit klarer Syntax
- Kompatibel mit Vue Router und der Composition API
- Leichtgewichtig und dennoch skalierbar für große Projekte
Pinia ist einfach nur eine lib, Sie mussen sie im main.ts (oder main.js) registrieren.
npm install pinia

Öffnen Sie die Hauptdatei (main.ts oder main.js) Ihres Projekts und importieren Sie Pinia. Anschließend erstellen Sie eine Instanz und registrieren sie in Ihrer Vue-App. Falls Sie bereits den Router verwenden, können Sie ihn gleich mit einbinden:
import { createApp } from 'vue'
import { createPinia } from 'pinia'
import './style.css'
import App from './App.vue'
const app = createApp(App)
const pinia = createPinia()
app.use(pinia)
app.mount('#app')

Erste Pinia-Store-Datei anlegen und in einer Komponente verwenden
Nachdem Pinia in Ihrem Projekt eingebunden ist, legen Sie nun den ersten Store an.
Ein Store dient als zentrale Quelle für Zustände (States), abgeleitete Werte (Getters) und Funktionen (Actions). Dadurch können Sie Daten und Logik an einem Ort bündeln – klar strukturiert und wiederverwendbar.
Erstellen Sie im Projektverzeichnis einen neuen Ordner stores (sofern noch nicht vorhanden) und legen Sie darin die Datei counter.ts an.
Ein Beispiel-Store könnte wie folgt aussehen:
import { defineStore } from 'pinia'
export const useCounterStore = defineStore('counter', {
state: () => ({
count: 0,
}),
getters: {
double: (state) => state.count * 2,
},
actions: {
increment() {
this.count++
},
},
})
Erläuterung:
stateenthält Ihre reaktiven Daten. Hier wird eine einfache Variablecountdefiniert.getterssind vergleichbar mit berechneten Eigenschaften (computed properties) und liefern abgeleitete Werte. In diesem Fall wirddoubleautomatisch neu berechnet, sobald sichcountändert.actionssind Methoden, mit denen Sie den State verändern – z. B. durch API-Aufrufe oder Logik, die mehrere Werte gleichzeitig anpasst.

Store in einer Komponente benutzen
Sobald der Store erstellt und global registriert wurde, können Sie ihn in jeder beliebigen Vue-Komponente verwenden.
Importieren Sie dazu einfach den Store und greifen Sie direkt auf seine Werte und Methoden zu.
Ein Beispiel in der App.vue oder einer beliebigen Komponente:
<script setup lang="ts">
import {useCounterStore} from "./stores/counter.ts"
const counter = useCounterStore()
function add() {
counter.increment()
}
</script>
<template>
<div>
<h1>Counter: {{ counter.count }}</h1>
<p>Double: {{ counter.double }}</p>
<button @click="add">+1</button>
</div>
</template>
<style scoped>
</style>


Wie es funktioniert:
- Mit
useCounterStore()holen Sie sich eine Instanz des Stores – vollständig reaktiv. - Änderungen an
counter.countwerden automatisch im Template aktualisiert. - Getter wie
counter.doubleverhalten sich wie computed-Properties. - Aktionen (hier
increment()) führen Änderungen sicher und zentral durch.
Damit ist der grundlegende Aufbau abgeschlossen.
Im nächsten Schritt können Sie weitere Stores anlegen, gemeinsame Zustände aufteilen oder Ihren Store mit echten WordPress-API-Daten verbinden, die Sie später über eine .env-Datei konfigurieren.
Vue Router dazunehmen
In einer modernen Single-Page-Application (SPA) übernimmt der Vue Router die Navigation zwischen verschiedenen Seiten und Komponenten.
Anstatt jede Seite als eigene HTML-Datei zu laden, werden mit Vue Router Routen dynamisch innerhalb der Anwendung gewechselt – schnell, ohne Neuladen und perfekt für SEO-optimierte Strukturen mit klar definierten URLs.
Mit dem Router können Sie mehrere Views (Ansichten) definieren, etwa eine Startseite, eine Detailansicht oder ein Dashboard. Jede Route wird dabei mit einer Vue-Komponente verknüpft. So behalten Sie Übersicht, wenn Ihre Anwendung wächst, und trennen Layout, Daten und Logik sauber voneinander.
Installation
Führen Sie im Projektverzeichnis folgenden Befehl aus:
npm install vue-router
Damit installieren Sie das offizielle Routing-Paket für Vue 3.
Vorbereitung des Projekts für den nächsten Level
Bevor wir den Vue Router in die bestehende Anwendung integrieren, erweitern wir zunächst unser Ziel:
Der bisherige Store soll nicht nur einen Wert verdoppeln, sondern zusätzlich auch eine dreifache Berechnung ermöglichen. Das klingt nach einem kleinen Schritt, ist aber didaktisch wichtig, weil dabei sehr gut sichtbar wird, wie Pinia arbeitet.
Zur Erinnerung:
Mit Pinia speichern wir den Zählerwert (count) zentral im Store. Das bedeutet:
Wenn der Wert in einer Komponente erhöht wird, ist er in allen anderen Komponenten sofort aktualisiert – unabhängig davon, ob diese direkt verwandt sind oder nicht. Genau das unterscheidet ein globales State-Management von klassischen Prop-Ketten.
Damit wir das demonstrieren können – z. B. einmal in App.vue mit Double und auf einer eigenen Route mit Trippel – ergänzen wir unseren Store um eine weitere abgeleitete Eigenschaft.
Öffnen Sie Ihre Datei src/stores/counter.ts und ergänzen Sie die Getter:
trippel: (state) => state.count * 3

Was haben wir damit erreicht?
doublekönnen Sie wie bisher inApp.vueanzeigen.triplekönnen Sie in einer anderen Komponente (z. B.TrippelView.vue, die später über den Router geladen wird) verwenden.- Beide greifen auf denselben State (
count) zu. Wenn Sie also inApp.vueauf „+1“ klicken, sieht auch dieTrippelViewsofort den neuen Wert.
Genau das ist der Effekt, den wir gleich mit dem Router sichtbar machen wollen: ein globaler Store + mehrere Views = eine konsistente Anwendung.
Router in der App „ins Leben rufen“
Um den Router in Ihrer Anwendung zum Leben zu erwecken, legen Sie zunächst eine neue Datei mit dem Namen index.ts im Verzeichnis /src/router/ an.
Darin definieren Sie alle Navigationspunkte (Routen), also die Verbindungen zwischen bestimmten URLs und den zugehörigen Vue-Komponenten.
Mit diesem Schritt machen Sie Ihre Anwendung multiseitenfähig, ohne dass echte Seiten neu geladen werden müssen – ein zentraler Vorteil einer modernen Single-Page-Application (SPA).
Struktur-Empfehlung:
Es ist sinnvoll, für jede Route eine eigene View-Komponente anzulegen.
So bleibt der Code übersichtlich, und jede Seite kann ihre eigene Logik und Darstellung enthalten.
Diese Views speichern Sie idealerweise im Verzeichnis /src/views/ und geben ihnen sprechende Namen, wie zum Beispiel HomeView.vue oder TrippelView.vue.
Beispiel: HomeView.vue
<script setup lang="ts">
import { useCounterStore } from "../stores/counter"
const counter = useCounterStore()
function add() {
counter.increment()
}
</script>
<template>
<div>
<h1>Counter: {{ counter.count }}</h1>
<p>Double: {{ counter.double }}</p>
<button @click="add">+1</button>
</div>
</template>
<style scoped>
</style>
Beispiel: TrippelView.vue
<script setup lang="ts">
import { useCounterStore } from '../stores/counter'
const counter = useCounterStore()
function add() {
counter.increment()
}
</script>
<template>
<div>
<h1>Counter: {{ counter.count }}</h1>
<p>Trippel: {{ counter.trippel }}</p>
<button @click="add">+1</button>
</div>
</template>


Da wir nun zwei verschiedene View-Komponenten für unsere Navigation angelegt haben – eine für die Startseite (HomeView.vue) und eine für die dreifache Berechnung (TrippelView.vue) – ist es an der Zeit, auch den Router sauber zu strukturieren.
Neues Verzeichnis: router
Anstatt die Routen direkt in der Hauptdatei (main.ts) zu definieren, empfiehlt es sich, dafür ein eigenes Verzeichnis zu verwenden.
So bleibt Ihr Projekt klar gegliedert, und das Routing-Verhalten lässt sich bei wachsenden Anwendungen leichter erweitern oder warten.
Erstellen Sie im Projektverzeichnis /src/ einen neuen Ordner mit dem Namen router.
Darin legen Sie eine Datei index.ts an, die alle Ihre Routen und das Router-Verhalten zentral bündelt.
Beispiel: Router-Datei index.ts
import { createRouter, createWebHistory } from 'vue-router'
import HomeView from "../views/HomeView.vue"
import TrippelView from "../views/TrippelView.vue"
const router = createRouter({
history: createWebHistory(),
routes: [
{ path: '/', name: 'home', component: HomeView },
{ path: '/trippel', name: 'trippel', component: TrippelView },
],
})
export default router

Erläuterung:
- Das neue Verzeichnis
routerdient als zentrale Schaltstelle für alle Navigationsrouten. - Durch
createRouter()undcreateWebHistory()aktivieren Sie das Routing im modernen SPA-Stil – also ohne Hash-Symbole in der URL. - Jede Route verweist auf eine eigene View-Komponente, die Sie unter
/src/views/ablegen.
Router in der App aktivieren
Damit der Router tatsächlich aktiv ist, müssen Sie ihn in Ihrer Hauptdatei (main.ts) einbinden:
import { createApp } from 'vue'
import { createPinia } from 'pinia'
import router from "./router/index.ts"; //<= NEW
import './style.css'
import App from './App.vue'
const app = createApp(App)
const pinia = createPinia()
app.use(pinia)
app.use(router) //<= NEW
app.mount('#app')

Vorteile dieser Struktur:
- Das Projekt bleibt übersichtlich und skalierbar, besonders bei mehreren Routen.
- Änderungen am Navigationsverhalten lassen sich zentral in
router/index.tsumsetzen. - Ideal für künftige Erweiterungen wie authentifizierte Bereiche, dynamische Parameter oder WordPress-API-basierte Inhalte.
Router in der App aktivieren und zentrale Struktur aufräumen
Als letzten Schritt für den Einsatz des Routers nehmen wir Änderungen an der App.vue vor.
Diese Datei ist das Herzstück Ihrer Anwendung und fungiert als zentraler Einstiegspunkt für alle Views.
Da Sie nun Ihre Logik und Berechnungen (z. B. den Counter) in separaten Komponenten – also HomeView.vue und TrippelView.vue – ausgelagert haben, können Sie Ihre App.vue deutlich vereinfachen und bereinigen.
Ersetzen Sie den bisherigen Inhalt Ihrer App.vue durch folgenden Code:
<script setup lang="ts">
</script>
<template>
<div>
<RouterView />
<hr>
<nav>
<RouterLink to="/">Home</RouterLink> |
<RouterLink to="/trippel">Trippel-View</RouterLink>
</nav>
</div>
</template>
<style scoped>
</style>
Erklärung des Codes
<RouterView />
Diese Komponente ist der Platzhalter für die aktuell aktive Route.
Wenn Sie auf den Link „Home“ klicken, wird automatisch die KomponenteHomeView.vuegeladen.
Wechseln Sie auf „Trippel-View“, zeigt Vue Router stattdessenTrippelView.vuean – alles ohne Seitenreload.<RouterLink>
Mit diesen Komponenten erstellen Sie interne Navigationslinks, die auf die in Ihrerrouter/index.tsdefinierten Pfade zeigen.to="/"ruft die Home-Ansicht auf.to="/trippel"öffnet die Seite mit der dreifachen Berechnung.
Vue Router sorgt dabei dafür, dass sich die URL im Browser anpasst und gleichzeitig der passende Inhalt im<RouterView>angezeigt wird.
<hr>und<nav>
Dienen hier nur zur besseren Strukturierung und Lesbarkeit. Das<hr>trennt optisch den Hauptinhalt von der Navigation, während<nav>Ihre Navigationslinks bündelt.



Zusammenfassung des gesamten Beitrags
In diesem Beitrag haben Sie Schritt für Schritt gesehen, wie aus einer einfachen Vue-3-Anwendung eine solide, erweiterbare Struktur entsteht:
- Pinia einbinden – Sie haben das offizielle State-Management-System in den Entry-Point integriert, um globale Zustände zentral zu verwalten.
- Ersten Store anlegen – Mit einem einfachen Counter-Store haben Sie die Grundlagen für reaktive Daten, Getter und Actions geschaffen.
- Store in Komponenten nutzen – Sie haben gelernt, wie Sie den globalen Zustand in beliebigen Komponenten abrufen und ändern können.
- Store erweitern – Der Counter wurde um eine zusätzliche Berechnung (Trippel) ergänzt, um die Wiederverwendbarkeit von Pinia zu verdeutlichen.
- Vue Router einführen – Sie haben Navigation und Routen definiert, um mehrere Views sauber zu trennen und miteinander zu verbinden.
- App-Struktur optimieren – Die
App.vuewurde bereinigt und dient nun als zentrale Steuerung mit<RouterView>und<RouterLink>für die Navigation.
Mit dieser Grundlage ist Ihr Projekt technisch sauber aufgebaut und optimal vorbereitet, um im nächsten Schritt echte Inhalte und API-Daten einzubinden – zum Beispiel aus einem WordPress-Backend oder einem anderen Headless-CMS.