systematische Qualitätssicherung für Vue 3-Projekte
Code Reviews in Vue-Teams scheitern oft nicht am Willen, sondern am fehlenden Framework. Ohne klare Kriterien werden Reviews zu subjektiven Stildebatten statt zu echten Qualitätschecks. Dieser Artikel zeigt, welche Prüfmuster wirklich wichtig sind — von Komponenten-Design über Reaktivitätsfehler bis zu Pinia-Store-Qualität und TypeScript-Integration.
Inhaltsverzeichnis
- 1. Warum Review-Patterns für Vue-Teams unverzichtbar sind
- 2. Komponenten-Design: Single Responsibility und Props-Kontrakte
- 3. Reaktivitätsfehler: die häufigsten Vue-Code-Review-Funde
- 4. Composables: Qualitätskriterien für wiederverwendbare Logik
- 5. Pinia-Stores: was im Review geprüft werden muss
- 6. TypeScript-Integration: Typen als Review-Qualitätsmarker
- 7. Template-Qualität: v-if, v-for und key-Handling
- 8. Performance-Checks im Vue Code Review
- 9. Review-Kriterien im Überblick
- 10. Zusammenfassung
- 11. FAQ
1. Warum Review-Patterns für Vue-Teams unverzichtbar sind
Ein Vue Code Review ohne definierte Prüfkriterien ist ein Gespräch über Geschmack. Der eine Reviewer fragt nach Naming-Konventionen, der andere diskutiert über Tab-Einrückung, während kritische Reaktivitätsfehler oder fehlerhafte Prop-Validierung unbemerkt in den Main-Branch landen. Strukturierte Vue Code Review-Patterns verlagern das Gespräch weg von Stilfragen hin zu messbaren Qualitätsmerkmalen: Ist die Komponente testbar? Sind die Props typisiert? Wird Reaktivität korrekt genutzt? Das sind Fragen mit klaren Antworten, keine Geschmackssache.
Der zweite Grund für systematische Vue Code Review-Patterns ist Konsistenz über Zeitpunkte und Reviewer hinweg. In einem Team mit drei Entwicklern reviewt Person A heute, Person B morgen und Person C nächste Woche. Ohne gemeinsame Checkliste variieren die Maßstäbe erheblich. Eine dokumentierte Review-Checkliste ist kein Misstrauensbeweis gegenüber Entwicklern, sondern ein Werkzeug, das die Review-Qualität entkoppelt von der Erfahrung und Tagesform des Reviewers. Neue Teammitglieder lernen durch die Checkliste gleichzeitig die Projektstandards kennen.
Vue 3 und die Composition API haben die Angriffsfläche für typische Review-Befunde verändert. Mit der Options API war das Problem oft fehlendes this-Binding oder der falsche Mixin-Einsatz. Mit der Composition API sind es Reaktivitätsverlust beim Destructuring, fehlende Cleanup-Funktionen in watchEffect und unkontrollierte Seiteneffekte in Composables. Wer seinen Vue Code Review-Prozess noch auf Options-API-Muster ausgerichtet hat, übersieht die neuen Fehlerquellen der Composition API.
2. Komponenten-Design: Single Responsibility und Props-Kontrakte
Das erste Qualitätsmerkmal im Vue Code Review ist Komponentengröße und Verantwortung. Eine Komponente, die mehr als eine Bildschirmseite Code hat und sowohl Datenfetching, Geschäftslogik als auch Rendering verantwortet, ist ein klares Review-Signal. Die Single-Responsibility-Frage: Kann man in einem Satz beschreiben, was diese Komponente tut? Wenn nicht, gehört sie aufgeteilt. Das Container/Presentational-Pattern trennt Datenbeschaffung (Container-Komponente mit Store-Zugriff) von Rendering (Presentational-Komponente, die nur Props erhält).
Props-Kontrakte sind das zweite wichtige Review-Kriterium. Jede Prop muss einen expliziten Typ haben — in TypeScript-Projekten über das defineProps<{ propName: Type }>()-Pattern, in JavaScript-Projekten über die Objekt-Syntax mit type und required. Ein Vue Code Review sollte Props ohne Typen als Review-Blocker behandeln, nicht als optionale Empfehlung. Emits müssen genauso deklariert werden: defineEmits<{ eventName: [payload: Type] }>(). Undokumentierte Emits sind eine versteckte API, die bei Refactoring unsichtbare Brüche erzeugt.
// WRONG: untyped props, undeclared emits, mixes concerns
// ProductCard.vue — no props types, implicit emits, fetches own data
const props = defineProps(['id', 'title']) // no types, no required
const emit = defineEmits(['click']) // no payload type
const data = await fetch(`/api/products/${props.id}`) // fetches own data
// RIGHT: typed props, declared emits, presentational component only
// ProductCard.vue — receives fully typed data, emits typed events
interface Props {
productId: string
title: string
price: number
inStock: boolean
}
const props = defineProps<Props>()
const emit = defineEmits<{
addToCart: [productId: string, quantity: number]
viewDetails: [productId: string]
}>()
// No data fetching — parent or store provides data
// Component only renders what it receives
3. Reaktivitätsfehler: die häufigsten Vue-Code-Review-Funde
Reaktivitätsverlust durch Destructuring ist der häufigste Fehler im Vue Code Review von Composition-API-Code. const { count } = useCounterStore() — count ist jetzt eine normale Zahl, keine Ref. Änderungen am Store spiegeln sich nicht in der Komponente. Das korrekte Muster: const { count } = storeToRefs(useCounterStore()) für State und Getters, direktes Destructuring nur für Actions. Im Vue Code Review sucht man nach jedem Destructuring-Zugriff auf Store-State und prüft, ob storeToRefs() verwendet wird.
Das zweite häufige Reaktivitätsproblem ist fehlende Cleanup bei watch und watchEffect. In watchEffect kann eine Cleanup-Funktion zurückgegeben werden, die vor dem nächsten Lauf oder beim Unmount der Komponente aufgerufen wird. Ohne Cleanup entstehen Memory Leaks — besonders bei Event-Listener-Registrierungen oder Timer-Setups innerhalb von Watchern. Ein Vue Code Review-Check: Jedes watchEffect und watch mit Seiteneffekten (addEventListener, setInterval, WebSocket-Verbindungen) muss eine Cleanup-Funktion haben.
4. Composables: Qualitätskriterien für wiederverwendbare Logik
Composables sind das mächtigste Feature der Composition API, aber auch die größte Quelle für Qualitätsprobleme im Vue Code Review. Das erste Kriterium: Ein Composable muss von seinem Namen her klar kommunizieren, was es tut. useProductData() ist unklar — lädt es Daten? Hält es State? Validiert es? useFetchProduct(id) oder useProductStore() sind selbsterklärend. Das Benennen ist kein Stilproblem, sondern ein Dokumentationsproblem: Andere Entwickler müssen aus dem Namen verstehen, was das Composable tut.
Das zweite Kriterium: Composables, die Seiteneffekte registrieren, müssen diese beim Unmount bereinigen. Das Muster ist onUnmounted oder die Rückgabe einer Cleanup-Funktion. Ein Composable, das einen addEventListener im Body registriert und nicht bereinigt, erzeugt einen Memory Leak, der sich über Seitennavigationen aufbaut. Im Vue Code Review gilt: Jedes Composable mit Seiteneffekten wird auf Cleanup geprüft. Das dritte Kriterium ist die Testbarkeit: Kann das Composable isoliert in einem Unit-Test aufgerufen werden? Composables mit direkten DOM-Zugriffen, festen URL-Strings oder globalen Singleton-Abhängigkeiten sind schwer testbar und müssen refactoriert werden.
5. Pinia-Stores: was im Review geprüft werden muss
Pinia-Stores haben im Vue Code Review eigene Qualitätskriterien. Das erste: Async Actions müssen Loading- und Error-State führen. Ein Store, der API-Aufrufe macht, ohne isLoading und error im State zu setzen, zwingt Komponenten, eigene Loading-States zu führen — was zu Inkonsistenzen führt. Das zweite Kriterium: State-Änderungen dürfen nur in Actions erfolgen, nicht direkt aus Komponenten heraus. Eine Komponente, die direkt store.items.push() aufruft, umgeht den Store-Kontrakt und macht den Datenfluss unsichtbar für DevTools und Tests.
Das dritte Pinia-Review-Kriterium ist Store-Komposition. Wenn eine Komponente zwei Stores importiert und deren Daten kombiniert, um einen abgeleiteten Wert zu berechnen, gehört diese Berechnung in einen Getter oder eine Action, die beide Stores zusammenführt. Berechnungslogik in Komponenten-Templates, die von mehreren Store-Werten abhängt, ist ein Review-Signal. Viertes Kriterium: Store-IDs müssen eindeutig und beschreibend sein — nicht useStore oder useMainStore, sondern useCartStore, useAuthStore, useCheckoutStore.
// Vue Code Review: Pinia anti-pattern vs. correct pattern
// WRONG: component directly mutates store state
// In ProductList.vue:
const store = useProductStore()
store.products.push(newProduct) // direct mutation — bypasses DevTools tracking
// WRONG: loading state managed in component
const isLoading = ref(false)
const loadProducts = async () => {
isLoading.value = true
store.products = await api.getProducts()
isLoading.value = false
}
// RIGHT: store manages its own loading and error state
// In stores/product.ts:
const fetchProducts = async () => {
isLoading.value = true
lastError.value = null
try {
products.value = await api.getProducts()
} catch (err) {
lastError.value = err instanceof Error ? err.message : 'Fetch failed'
} finally {
isLoading.value = false
}
}
// In component: just call the action, read reactive state
const store = useProductStore()
onMounted(() => store.fetchProducts())
// template: v-if="store.isLoading", v-if="store.lastError"
6. TypeScript-Integration: Typen als Review-Qualitätsmarker
TypeScript-Qualität ist ein eigenständiges Review-Kriterium im Vue Code Review. Das offensichtlichste Problem: any-Typen. Ein any in einer Funktion, einem Prop oder einer API-Response-Definition ist eine Lücke im Typ-System — an dieser Stelle gibt TypeScript keine Garantien mehr. Im Vue Code Review sind any-Typen Review-Blocker oder zumindest Review-Kommentare mit Begründungspflicht. Die Alternative zu any ist fast immer unknown mit expliziter Typ-Prüfung oder ein korrektes Interface für die betreffende Struktur.
Das zweite TypeScript-Kriterium: Return-Typen für öffentliche Funktionen in Composables und Stores müssen explizit deklariert sein. TypeScript kann Return-Typen ableiten, aber explizite Deklarationen machen die API des Composables dokumentiert und verhindern, dass Refactoring versehentlich den Return-Typ verändert ohne Compile-Fehler. Das dritte Kriterium: Template-Ref-Typen müssen korrekt typisiert sein. const inputRef = ref<HTMLInputElement | null>(null) — nicht ref(null). Falsche oder fehlende Template-Ref-Typen erzeugen Laufzeitfehler, die TypeScript hätte verhindern können.
7. Template-Qualität: v-if, v-for und key-Handling
Template-Code wird im Vue Code Review häufig weniger streng geprüft als Script-Code, obwohl er genauso viele Fehlerquellen hat. Das erste Kriterium: v-if und v-for nie auf demselben Element. Die Auswertungsreihenfolge (in Vue 2: v-for zuerst, in Vue 3: v-if zuerst) führt zu unerwartetem Verhalten und ist schwer zu debuggen. Das korrekte Muster: v-for auf dem äußeren Element, v-if auf einem inneren Element oder das Vorfiltern der Liste in einem Getter.
Das zweite Template-Kriterium ist das :key-Attribut bei v-for. Ein :key mit dem Array-Index (:key="index") ist fast immer falsch — Vue kann so keine Unterschiede zwischen den Elementen erkennen und rendert bei Listenänderungen alle Elemente neu. Der korrekte Key ist eine stabile, eindeutige ID aus den Daten: :key="product.id". Im Vue Code Review ist jedes :key="index" ein Kommentar wert, weil es zu sichtbaren Performance-Problemen bei animierten Listen führt. Drittes Kriterium: Komplexe Ausdrücke im Template gehören in Computed Properties, nicht als Inline-JavaScript im Template.
8. Performance-Checks im Vue Code Review
Performance-Probleme sind im Vue Code Review schwieriger zu erkennen als funktionale Fehler, weil sie oft erst bei größeren Datensätzen oder häufigeren Updates sichtbar werden. Das erste Performance-Review-Kriterium: unnötige Reaktivität. Ein großes Objekt, das nur zur initialen Anzeige gerendert wird und sich nie ändert, sollte nicht mit reactive() oder ref() gewrapped werden. Object.freeze() oder die direkte Verwendung als Props-Default verhindern, dass Vue einen reaktiven Proxy für diese Daten erstellt.
Das zweite Performance-Kriterium: Getter-Missbrauch. Ein Getter, der eine komplexe Sortier- oder Filteroperation ausführt, wird bei jeder Änderung des abhängigen States neu berechnet. Wenn dieser State sehr häufig wechselt (z.B. bei Live-Suche), kann das zu spürbaren Render-Verzögerungen führen. Das Review-Muster: Getter sollten reine Transformationen ohne Seiteneffekte sein und auf einer stabilen State-Basis arbeiten. Für aufwendige Berechnungen über große Datensätze empfiehlt sich computed() mit explizitem Caching oder das Vorgenerieren berechneter Werte in Actions. Drittes Kriterium: v-show vs. v-if — bei häufig toggelnden Elementen ist v-show effizienter, weil kein DOM-Node neu erstellt wird.
9. Review-Kriterien im Überblick
Nicht jedes Review-Problem hat dasselbe Gewicht. Dieser Überblick zeigt, welche Befunde als Review-Blocker behandelt werden sollten und welche als informelle Kommentare akzeptabel sind.
| Bereich | Review-Blocker | Review-Kommentar | Grund |
|---|---|---|---|
| Typsystem | any ohne Begründung | Fehlende Return-Typen | any bricht TypeScript-Garantien |
| Reaktivität | Destructuring ohne storeToRefs | Unnötige reactive() Wraps | Reaktivitätsverlust ist ein Laufzeitfehler |
| Pinia | Direkte State-Mutation aus Komponenten | Fehlende isLoading-Flags | Umgeht DevTools und Tests |
| Template | v-if + v-for auf gleichem Element | :key="index" bei statischen Listen | Undefined Behavior in Vue 3 |
| Composables | Seiteneffekte ohne onUnmounted-Cleanup | Undeutliche Composable-Namen | Memory Leak bei Seitennavigation |
Die Review-Checkliste kann in der CI/CD-Pipeline durch statische Analyse ergänzt werden. eslint-plugin-vue mit vue3-recommended-Ruleset prüft viele der oben genannten Kriterien automatisch: vue/no-use-v-if-with-v-for, vue/require-v-for-key, vue/no-unused-vars. Was die Linter nicht prüfen — Store-Architektur, Composable-Cleanup und TypeScript-Sinnhaftigkeit — bleibt menschlichen Reviewern vorbehalten. Ein guter Vue Code Review ist kein Ersatz für Linter, sondern deren sinnvolle Ergänzung.
Mironsoft
Vue 3 Code-Qualität und Team-Prozesse
Vue Code Reviews in eurem Team systematisieren?
Wir entwickeln Review-Checklisten, ESLint-Konfigurationen und Team-Standards für euer Vue 3-Projekt — abgestimmt auf eure Codebase und Team-Erfahrung.
Review-Checklisten
Projektspezifische Checklisten für Komponenten, Stores und Composables
ESLint-Setup
eslint-plugin-vue und TypeScript-ESLint für automatische Code-Qualität in CI/CD
Team-Workshop
Gemeinsames Review realer PRs mit Fokus auf Vue 3-spezifische Qualitätsmuster
10. Zusammenfassung
Ein effektiver Vue Code Review prüft systematisch die Bereiche, in denen Vue 3-Projekte typischerweise Qualitätsprobleme entwickeln. Reaktivitätsverlust durch Destructuring, fehlende Cleanup in Composables und direkte State-Mutation in Komponenten sind die häufigsten Blocker-Befunde. TypeScript-any-Typen und falsch eingesetztes v-if + v-for auf demselben Element folgen dicht dahinter. Eine Review-Checkliste macht diese Prüfpunkte unabhängig vom jeweiligen Reviewer konsistent anwendbar.
Der praktische Ansatz: Statische Analyse mit eslint-plugin-vue und TypeScript-ESLint in der CI-Pipeline automatisiert die prüfbaren Kriterien. Was Linter nicht erkennen — Architekturentscheidungen, Store-Komposition, Composable-Design — bleibt für menschliche Reviews reserviert. So ist die Review-Zeit auf die Befunde konzentriert, die wirklich menschliches Urteil erfordern, statt auf mechanisch prüfbare Regeln verschwendet zu werden.
Vue Code Reviews — Das Wichtigste auf einen Blick
Reaktivität
Destructuring aus Stores nur mit storeToRefs(). Watch/watchEffect mit Seiteneffekten brauchen Cleanup-Funktionen.
TypeScript
any ohne Begründung ist ein Review-Blocker. Props, Emits und Return-Typen von Composables müssen explizit deklariert sein.
Pinia-Stores
State-Änderungen nur über Actions. Async Actions mit isLoading und error im Store-State. Store-IDs eindeutig und beschreibend.
Template
Nie v-if + v-for auf demselben Element. :key immer stabile ID, kein Array-Index. Komplexe Ausdrücke in Computed Properties.