Vuex & Pinia – State Management

6 Kernkonzepte
Die wichtigsten Konzepte für State Management in Vue: Vuex · Pinia · State · Getters · Actions · Modules / Stores Vuex war der offizielle State-Manager für Vue 2. Pinia ist der moderne Nachfolger für Vue 3 und bietet eine einfachere, typsicherere API. Diese Cheatsheet zeigt beide im Vergleich.

Vuex – Klassisches State Management (Vue 2 & 3)

state · mutations · actions · getters · modules
// store.js (Vuex) import { createStore } from 'vuex'; export const store = createStore({ state: () => ({ count: 0 }), mutations: { increment(state) { state.count++; } }, actions: { incrementAsync({ commit }) { setTimeout(() => commit('increment'), 1000); } }, getters: { doubleCount: (state) => state.count * 2 } });

Vuex ist der klassische State-Manager für Vue. Er folgt einem strikten Flux-Pattern mit State (Daten), Mutations (synchrone Änderungen), Actions (asynchrone Operationen) und Getters (abgeleitete Werte).

Vuex Kernkonzepte

Konzept Beschreibung Zugriff in Komponente
State Zentraler Zustand (Daten) $store.state.count
Getters Abgeleitete Werte (cached) $store.getters.doubleCount
Mutations Synchrone Zustandsänderungen $store.commit('increment')
Actions Asynchrone Operationen $store.dispatch('incrementAsync')
Modules Aufteilung in Unter-Stores $store.state.moduleName
Beispiele
// store.js
import { createStore } from 'vuex';
export const store = createStore({
state: () => ({
user: null,
posts: []
}),
mutations: {
setUser(state, user) { state.user = user; },
setPosts(state, posts) { state.posts = posts; }
},
actions: {
async fetchUser({ commit }) {
const res = await fetch('/api/user');
commit('setUser', await res.json());
}
},
getters: {
isLoggedIn: (state) => state.user !== null,
postCount: (state) => state.posts.length
}
});
// In Komponente (Options API)
computed: {
count() { return this.$store.state.count; },
double() { return this.$store.getters.doubleCount; }
},
methods: {
increment() { this.$store.commit('increment'); },
incrementAsync() { this.$store.dispatch('incrementAsync'); }
}
Tipp: Vuex verwendet Mutations für synchrone Änderungen und Actions für Asynchronität. Getters sind cached und werden nur neu berechnet, wenn sich Abhängigkeiten ändern.

Pinia – Modernes State Management (Vue 3)

defineStore · state · getters · actions
// store.js (Pinia) import { defineStore } from 'pinia'; export const useCounterStore = defineStore({ id: 'counter', state: () => ({ count: 0 }), getters: { doubleCount: (state) => state.count * 2 }, actions: { increment() { this.count++; } } });

Pinia ist der moderne Nachfolger von Vuex für Vue 3. Es bietet eine einfachere API, bessere TypeScript-Unterstützung und benötigt keine Mutations mehr – Actions können sowohl synchron als auch asynchron sein.

Pinia vs Vuex

Merkmal Vuex Pinia
Mutations Erforderlich Nicht erforderlich
Actions Nur asynchron Synchon & asynchron
TypeScript Eingeschränkt Native Unterstützung
Store-Struktur Module Mehrere Stores
Devtools Unterstützt Unterstützt
Vue-Version Vue 2 & 3 Vue 3 (auch Vue 2 mit Plugin)
Beispiele
// stores/counter.js
import { defineStore } from 'pinia';
export const useCounterStore = defineStore({
id: 'counter',
state: () => ({
count: 0,
user: null
}),
getters: {
doubleCount: (state) => state.count * 2,
isLoggedIn: (state) => state.user !== null
},
actions: {
increment() {
this.count++;
},
async fetchUser() {
const res = await fetch('/api/user');
this.user = await res.json();
},
reset() {
this.count = 0;
this.user = null;
}
}
});
// In Komponente (Composition API)
import { useCounterStore } from '@/stores/counter';
const counter = useCounterStore();
const count = counter.count; // Zugriff auf State
const double = counter.doubleCount; // Zugriff auf Getter
counter.increment(); // Action aufrufen
await counter.fetchUser(); // Asynchrone Action
Tipp: Pinia ist die empfohlene State-Management-Lösung für Vue 3. Es ist einfacher, typsicherer und benötigt keine Mutations mehr – Actions können direkt den State verändern.

State & Getters – Daten und abgeleitete Werte

state · getters · mapState · storeToRefs
// Vuex computed: { ...mapState(['count']), ...mapGetters(['doubleCount']) } // Pinia const store = useCounterStore(); const { count, doubleCount } = storeToRefs(store);

State enthält die zentralen Daten. Getters sind abgeleitete Werte, die automatisch aktualisiert werden. In Komponenten können Sie mit mapState (Vuex) oder storeToRefs (Pinia) auf sie zugreifen.

Beispiele
// Vuex: mapState und mapGetters
import { mapState, mapGetters } from 'vuex';
export default {
computed: {
...mapState(['count', 'user']),
...mapGetters(['doubleCount', 'isLoggedIn'])
}
}
// Pinia: storeToRefs
import { storeToRefs } from 'pinia';
import { useCounterStore } from '@/stores/counter';
const store = useCounterStore();
const { count, user } = storeToRefs(store);
// Getters sind auch in storeToRefs enthalten
const { doubleCount, isLoggedIn } = storeToRefs(store);
// Direkter Zugriff (ohne Reaktivität – vorsichtig!)
const countValue = store.count; // NUR für einmalige Abfragen
// State zurücksetzen
store.$reset(); // Pinia: setzt State auf Initialwert zurück
Tipp: Verwenden Sie storeToRefs in Pinia, um Reaktivität zu erhalten – sonst gehen reaktive Updates verloren. In Vuex bieten mapState und mapGetters die gleiche Funktionalität.

Actions – Zustandsänderungen durchführen

commit · dispatch · this · async
// Vuex Action actions: { async fetchData({ commit }) { const data = await api.getData(); commit('setData', data); } }

Actions sind für asynchrone Operationen und das Committen von Mutations (Vuex) oder direkte State-Änderungen (Pinia) verantwortlich. Sie können auch andere Actions aufrufen.

Beispiele
// Vuex: Actions mit Context
actions: {
updateUser({ commit, state }, userData) {
return new Promise((resolve) => {
// Asynchrone Operation
commit('setUser', userData);
resolve();
});
},
// Action ruft andere Action auf
async saveAll({ dispatch }) {
await dispatch('saveUser');
await dispatch('savePosts');
}
}
// Pinia: Actions mit this (direkter State-Zugriff)
actions: {
async updateUser(userData) {
// Direkter Zugriff auf State
this.user = userData;
// Andere Action aufrufen
await this.logAction('updateUser');
},
logAction(actionName) {
console.log(`Action: ${actionName}`);
}
}
// Aufruf in Komponente
store.updateUser({ name: 'Anna' });
await store.saveAll();
Tipp: In Pinia können Actions direkt den State verändern – es gibt keine Mutations mehr. Das macht den Code kürzer und verständlicher. In Vuex müssen Sie immer commit für State-Änderungen verwenden.

Modules / Stores – Strukturierung großer Anwendungen

modules · namespaced · defineStore
// Vuex Module modules: { user: { namespaced: true, state: () => ({ name: '' }) }, posts: { namespaced: true, state: () => ({ items: [] }) } }

Module (Vuex) und Stores (Pinia) ermöglichen die Aufteilung des State-Managements in logische Einheiten – ideal für große Anwendungen mit vielen Domänen.

Beispiele
// Vuex: Module mit namespaced
const userModule = {
namespaced: true,
state: () => ({ name: '', email: '' }),
mutations: {
setName(state, name) { state.name = name; }
},
getters: {
displayName: (state) => state.name || 'Gast'
}
};
// Zugriff auf namespaced Module
computed: {
...mapState('user', ['name']),
...mapGetters('user', ['displayName'])
},
methods: {
...mapMutations('user', ['setName'])
}
// Pinia: Mehrere Stores
// stores/user.js
export const useUserStore = defineStore({
id: 'user',
state: () => ({ name: '', email: '' })
});
// stores/posts.js
export const usePostsStore = defineStore({
id: 'posts',
state: () => ({ items: [] }),
getters: {
count: (state) => state.items.length
}
});
// In Komponente
import { useUserStore } from '@/stores/user';
import { usePostsStore } from '@/stores/posts';
const userStore = useUserStore();
const postsStore = usePostsStore();
const userName = userStore.name;
const postCount = postsStore.count;
// Store mit getters und actions
export const useAppStore = defineStore({
id: 'app',
state: () => ({ theme: 'dark' }),
getters: {
isDark: (state) => state.theme === 'dark'
},
actions: {
toggleTheme() {
this.theme = this.theme === 'dark' ? 'light' : 'dark';
}
}
});
Tipp: In Pinia gibt es keine Module mehr – Sie erstellen einfach mehrere Stores. Das ist einfacher und flexibler. Verwenden Sie namespaced: true in Vuex, um Kollisionen bei Actions und Getters zu vermeiden.

State Management im Überblick

Vuex Klassisch (Vue 2 & 3)
state, mutations, actions, getters, modules
Pinia Modern (Vue 3)
state, getters, actions, mehrere Stores
State Zentrale Daten
Reaktiv, von überall zugänglich
Getters Abgeleitete Werte
Cached, automatisch aktualisiert
Actions Zustandsänderungen
Async, Logik, API-Calls
storeToRefs Reaktive Store-Refs
Pinia: Reaktivität erhalten

Quick Summary

Vuex
Klassisch
Pinia
Modern
state
Daten
getters
Abgeleitet
actions
Änderungen
modules
Struktur
$store.commit('mutation') · $store.dispatch('action') · useCounterStore()