Communitygithub.com

vue-patterns

Vue.js 3 Composition API Patterns, Komponentenarchitektur, Reaktivität Best Practices, Pinia State Management, Vue Router Navigation und Nuxt SSR Patterns. Aktiviert für Vue-, Nuxt-, Vite- oder Pinia-Projekte. Verwenden beim Erstellen oder Überprüfen von Vue 3-, Nuxt- oder Pinia-Code – Composition API, Reaktivität oder Router-Navigation.

Was ist vue-patterns?

Diese Fähigkeit (Skill) bietet einen umfassenden Leitfaden für die Vue.js 3-Entwicklung mit der Composition API (`<script setup>`). Sie deckt Komponentendesign, Reaktivität, State Management mit Pinia, Routing, Testing und SSR-Patterns ab, einschließlich Nuxt-spezifischer Anleitungen, wo diese von Vanilla-Vue abweichen. Der Skill aktiviert sich automatisch für Projekte, die Vue.js, Nuxt, Vite + Vue oder Pinia verwenden, und unterstützt Entwickler beim Schreiben, Überprüfen und Optimieren von Vue 3-Code. Er enthält praktische Beispiele, klare Anti-Patterns und Best Practices für moderne Vue-Entwicklung, einschließlich der neuen APIs ab Vue 3.5+ wie reaktive Props-Destrukturierung, useTemplateRef() und onWatcherCleanup(). Entwickler können diesen Skill nutzen, um saubere, wartbare und leistungsstarke Vue-Anwendungen zu erstellen.

Funktioniert mit~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/affaan-m/ECC/tree/main/skills/vue-patterns

In Ihrer bevorzugten KI fragen

Öffnet einen neuen Chat, in dem dieser Agent-Skill bereits geladen ist.

Dokumentation

Vue.js Patterns und Best Practices

Umfassender Leitfaden für die Vue.js 3-Entwicklung mit der Composition API (<script setup>), der Komponentendesign, Reaktivität, State Management, Routing, Testing und SSR-Patterns abdeckt. Nuxt-spezifische Anleitungen sind enthalten, wo sie von Vanilla-Vue abweichen.

Wann aktivieren

Aktivieren Sie diesen Skill, wenn:

  • Das Projekt Vue.js (beliebige Version), Nuxt, Vite + Vue oder Pinia verwendet.
  • Der Benutzer nach Vue-Komponentenarchitektur, Composables, Reaktivität oder State Management fragt.
  • Vue Single-File Components (.vue-Dateien) überprüft werden.
  • Vue Router, Pinia Stores oder Vite/Vitest-Konfiguration eingerichtet wird.
  • Vue-spezifische Performance-, Sicherheits- oder SSR-Patterns diskutiert werden.

1. Projektstruktur

Empfohlene Struktur (Feature-First)

src/
├── api/              # API-Client und Endpunkt-Definitionen
├── assets/           # Statische Assets (Bilder, Schriften, Icons)
├── components/       # Geteilte/wiederverwendbare Komponenten
│   ├── base/         # Basis-UI-Primitive (Button, Input, Modal)
│   └── features/     # Featurespezifische geteilte Komponenten
├── composables/      # Wiederverwendbare Composition-API-Logik
├── layouts/          # Seitenlayouts (optional)
├── pages/            # Route-level Seitenkomponenten
├── router/           # Vue Router Konfiguration
├── stores/           # Pinia Stores
├── types/            # TypeScript-Typdefinitionen
├── utils/            # Reine Hilfsfunktionen
└── App.vue           # Root-Komponente

Dateibenennung

KonventionWann verwenden
PascalCase.vueAlle Komponenten (erzwungen durch vue/multi-word-component-names)
useCamelCase.tsComposables
camelCase.tsHilfsfunktionen, API-Clients, Typen
kebab-case-VerzeichnisseRoute-Segmente, Feature-Ordner

2. Komponentenarchitektur

Single-File Component Reihenfolge

<script setup lang="ts">
// 1. Imports (vue → ecosystem → absolut → relativ)
// 2. Props & Emits & Slots
// 3. Composables
// 4. Lokaler Zustand (ref/reactive)
// 5. Computed-Eigenschaften
// 6. Methoden
// 7. Watcher
// 8. Lifecycle-Hooks
</script>

<template>
  <!-- Template-Inhalt -->
</template>

<style scoped>
  /* Gültige Styles */
</style>

Präsentations- vs. Container-Komponenten

  • Container-Komponenten: Eigene Datenabrufe, Zustände und Seiteneffekte. Rendern Präsentationskomponenten.
  • Präsentationskomponenten: Empfangen Props, emittieren Events. Keine API-Aufrufe, kein Store-Zugriff. Reines Rendern.

Props Best Practices

// Typbasierte Props mit Standardwerten
interface Props {
  label: string;
  variant?: "primary" | "secondary";
  disabled?: boolean;
  items: Item[];
}

const props = withDefaults(defineProps<Props>(), {
  variant: "primary",
  disabled: false,
});
  • Immer type und required/default angeben, wo angemessen.
  • Boolesche Props: isXxx, hasXxx, canXxx.
  • Props niemals mutieren – stattdessen Events emittieren.
  • Für v-model-Bindung defineModel() (Vue 3.4+) oder modelValue + update:modelValue verwenden.

Events

const emit = defineEmits<{
  submit: [];
  "update:modelValue": [value: string];
  select: [id: string, index: number];
}>();
  • In Templates Kebab-Case verwenden (@update:model-value).
  • Im Script Camel-Case verwenden (emit("update:modelValue", val)).

3. Composables (Wiederverwendbare Logik)

Struktur

// composables/useDebounce.ts
export function useDebounce<T>(value: MaybeRef<T>, delay: number): Ref<T> {
  const debounced = ref(toValue(value)) as Ref<T>;

  let timer: ReturnType<typeof setTimeout>;
  watch(
    () => toValue(value),
    (newVal) => {
      clearTimeout(timer);
      timer = setTimeout(() => { debounced.value = newVal; }, delay);
    }
  );

  onUnmounted(() => clearTimeout(timer));
  return readonly(debounced);
}

Regeln

  • Muss mit dem Präfix use beginnen.
  • Reaktive Werte zurückgeben (ref, computed, reactive), niemals einfache Primitive.
  • Reaktive Eingaben über MaybeRef / toRef() / toValue() akzeptieren.
  • Seiteneffekte in onUnmounted oder Watcher onCleanup bereinigen.
  • Keine Seiteneffekte auf Modulebene.

vs Mixins

Composables ersetzen Vue 2 Mixins vollständig:

  • Mixins: Undurchsichtiger Datenfluss, Kollisionen bei Datenquellen, Namenskonflikte.
  • Composables: Explizite Imports, klare Rückgabewerte, zusammensetzbar und tree-shakable.

4. State Management

Wann was verwenden

PatternAnwendungsfall
ref() / reactive()Lokaler Komponentenzustand
Props + EmitsEltern-Kind-Kommunikation
Provide / InjectTheme, Konfiguration, Plugin-API
Pinia StoreGlobaler, geteilter, komplexer Zustand
Serverzustand-ComposableAPI-Daten mit Caching (wrapper für fetch/TanStack Query)

Pinia Setup Store (Bevorzugt)

// stores/useCartStore.ts
export const useCartStore = defineStore("cart", () => {
  const items = ref<CartItem[]>([]);
  const isLoading = ref(false);

  const totalPrice = computed(() =>
    items.value.reduce((sum, i) => sum + i.price * i.quantity, 0)
  );
  const itemCount = computed(() =>
    items.value.reduce((sum, i) => sum + i.quantity, 0)
  );

  async function addItem(productId: string) {
    isLoading.value = true;
    try {
      const item = await fetchProduct(productId);
      const existing = items.value.find(i => i.id === item.id);
      if (existing) existing.quantity++;
      else items.value.push({ ...item, quantity: 1 });
    } finally {
      isLoading.value = false;
    }
  }

  return { items, isLoading, totalPrice, itemCount, addItem };
});
  • Setup Store-Syntax (nicht Options Store) verwenden.
  • Aktionen für Business-Level-Mutationen und $patch() für gruppierte Updates bevorzugen.
  • Jede asynchrone Aktion: Ladevorgang + Erfolg + Fehler behandeln.

5. Vue Router

Route-Definitionen

const routes = [
  {
    path: "/users/:id",
    name: "user-detail",
    component: () => import("@/pages/UserDetail.vue"), // lazy
    props: true, // params als Props übergeben
    meta: { requiresAuth: true },
  },
];

Navigations-Guards

router.beforeEach((to, from) => {
  const { isLoggedIn } = useAuthStore();
  if (to.meta.requiresAuth && !isLoggedIn) {
    return { name: "login", query: { redirect: to.fullPath } };
  }
});

Reaktive Route-Parameter

Wenn eine Komponente gemountet bleibt, aber die Route-Parameter sich ändern:

const route = useRoute();
const id = computed(() => route.params.id as string);
watch(id, (newId) => fetchItem(newId));

6. Template-Patterns

Template-Syntax

<!-- v-if/v-else-if/v-else -->
<div v-if="isLoading">Lädt...</div>
<div v-else-if="error">Fehler: {{ error }}</div>
<div v-else>{{ content }}</div>

<!-- v-show für häufige Umschaltungen -->
<div v-show="isOpen">Umschaltbarer Inhalt</div>

<!-- v-for mit stabilen Keys -->
<div v-for="item in items" :key="item.id">{{ item.name }}</div>

<!-- Berechnete gefilterte Liste (nicht v-if + v-for auf demselben Element) -->
<div v-for="item in activeItems" :key="item.id">{{ item.name }}</div>

<!-- Event-Handling -->
<form @submit.prevent="handleSubmit">
  <button type="submit">Speichern</button>
</form>

<!-- v-model -->
<input v-model="name" />
<CustomInput v-model="value" v-model:title="title" />

7. Performance

TechnikWann verwenden
v-memoListenelemente, die sich selten ändern
v-onceInhalt, der einmal gerendert wird und für immer statisch ist
shallowRef()Große Datenstrukturen, die vollständig ersetzt werden
shallowReactive()Nur Eigenschaften der obersten Ebene sind reaktiv
v-show über v-ifHäufige Sichtbarkeitsumschaltungen
<KeepAlive :max="10">Zwischenspeichern umgeschalteter Ansichten
Lazy Routes() => import(...) für nicht kritische Routen
SuspenseAsynchrones Laden von Komponenten mit Fallback

8. Testing

Stack

  • Vitest für Unit- und Komponententests
  • Vue Test Utils zum Mounten und für Interaktionen
  • @pinia/testing für Store-Mocking
  • Playwright für E2E

Komponententest-Muster

import { mount } from "@vue/test-utils";
import { createPinia, setActivePinia } from "pinia";
import UserCard from "./UserCard.vue";

beforeEach(() => { setActivePinia(createPinia()); });

it("renders and emits", async () => {
  const wrapper = mount(UserCard, {
    props: { user: { id: "1", name: "Alice" } },
  });
  expect(wrapper.text()).toContain("Alice");
  await wrapper.find("button").trigger("click");
  expect(wrapper.emitted("select")![0]).toEqual(["1"]);
});

9. Nuxt-spezifische Patterns

Auto-Imports

Nuxt importiert ref, computed, watch, useFetch, useAsyncData usw. automatisch. Verwenden Sie sie direkt ohne Import. Bei Nicht-Nuxt-Projekten immer explizit importieren.

useAsyncData / useFetch

const { data: user, pending, error, refresh } = await useAsyncData(
  "user", // eindeutiger Key für Caching
  () => $fetch(`/api/users/${id}`),
);

const { data: posts } = await useFetch("/api/posts", {
  query: { page: 1 },
  key: "posts-page-1", // dedupliziert Anfragen
});

Server-Routen

// server/api/users/[id].ts
export default defineEventHandler(async (event) => {
  const { id } = await getValidatedRouterParams(event, z.object({
    id: z.string().uuid(),
  }).parse);
  // ... abrufen und zurückgeben
});

Runtime Config

// nuxt.config.ts
export default defineNuxtConfig({
  runtimeConfig: {
    // Server-seitig
    apiSecret: "",
    // öffentlich (dem Client zugänglich)
    public: {
      apiBase: "https://api.example.com",
    },
  },
});

10. Vue 3.5+ Neue APIs

Reaktive Props Destrukturierung

Vue 3.5 hat die reaktive Props Destrukturierung stabilisiert – destrukturierte Variablen von defineProps() sind automatisch reaktiv:

// Vue 3.5+: destrukturierte Props sind reaktiv (kein toRefs nötig)
const { count = 0, msg = "hallo" } = defineProps<{
  count?: number;
  msg?: string;
}>();

// Einschränkung: Kann destrukturierte Props nicht direkt watchen
watch(() => count, (newVal) => { ... }); // OK: Getter erforderlich

useTemplateRef()

Ersetzen Sie namensgleiche einfache Refs mit useTemplateRef() für Template-Referenzen:

import { useTemplateRef } from "vue";
const inputEl = useTemplateRef<HTMLInputElement>("input");
// "input" entspricht dem ref="input"-Attribut im Template, nicht dem Variablennamen

Unterstützt dynamische Ref-IDs: useTemplateRef(dynamicRefId).

onWatcherCleanup()

Global importierbare Watcher-Bereinigungs-API (Vue 3.5+). Sie muss synchron innerhalb des Watcher-Callbacks aufgerufen werden:

import { watch, onWatcherCleanup } from "vue";

watch(userId, async (newId) => {
  const controller = new AbortController();
  onWatcherCleanup(() => controller.abort());
  // ... mit Signal abrufen
});

useId()

SSR-stable eindeutige ID-Generierung für Formularelemente und Barrierefreiheit:

import { useId } from "vue";
const id = useId();

defer Teleport

<Teleport defer> ermöglicht das Teleportieren zu Zielen, die im selben Zyklus gerendert werden:

<Teleport defer to="#container">Inhalt</Teleport>
<div id="container"></div>

Lazy Hydration (SSR)

defineAsyncComponent() unterstützt jetzt die hydrate-Strategie:

import { defineAsyncComponent, hydrateOnVisible } from "vue";
const AsyncComp = defineAsyncComponent({
  loader: () => import("./Comp.vue"),
  hydrate: hydrateOnVisible(),
});

Anti-Patterns

Anti-PatternWarum es falsch istDie Behebung
defineProps() destrukturieren (Vue < 3.5)Erfasst einen Snapshot, verliert ReaktivitätZugriff über props.xxx oder toRefs() verwenden
watch() auf destrukturierte Props (Vue 3.5+)Compile-Time-Fehler – destrukturierte Props können nicht direkt ge watched werdenGetter-Wrapper verwenden: watch(() => count, ...)
v-if + v-for auf demselben ElementMehrdeutige AusführungsreihenfolgeBerechnetes gefiltertes Array verwenden
v-for Key = IndexKaputter Zustand bei NeuanordnungStabile Datenbank-IDs verwenden
Props mutierenVerstößt gegen unidirektionalen DatenflussEvents emittieren oder v-model verwenden
v-html mit BenutzerinhaltenXSS-SicherheitslückeMit DOMPurify bereinigen
Mixins in Vue 3Undurchsichtig, kollisionsanfälligDurch Composables ersetzen
Seiteneffekte auf Modulebene im ComposableÜber Instanzen hinweg geteiltInnerhalb von onMounted + onUnmounted eingerenzen
reactive() für ersetzbaren ZustandErsetzung bricht Reaktivitätref() stattdessen verwenden
Watcher ohne BereinigungSpeicherlecks, Race ConditionsonCleanup oder onWatcherCleanup() (Vue 3.5+) verwenden
Options-API in neuem Vue 3 CodeÖkosystem bewegt sich zur Composition API<script setup> verwenden
Einfache Ref für Template-ReferenzenKeine dynamische Ref-Unterstützung, Namensabgleich fragiluseTemplateRef() (Vue 3.5+) verwenden

Verwandte Skills

  • accessibility — ARIA, semantisches HTML, Fokus-Management
  • frontend-patterns — Framework-übergreifende Frontend-Architektur
  • typescript — TypeScript Best Practices für Vue-Projekte
  • coding-standards — Allgemeine Code-Qualitätsstandards

Individual skills in this repo

This repo contains 20 individual skills — each has its own dedicated page.

accessibility

Design, implement, and audit inclusive digital products using WCAG 2.2 Level AA. Use when building or auditing UI that must meet WCAG 2.2 Level AA, or when reviewing a change for keyboard, contrast, or screen-reader support.

affaan-m/content-engine

Create platform-native content systems for X, LinkedIn, TikTok, YouTube, newsletters, and repurposed multi-platform campaigns. Use when the user wants social posts, threads, scripts, content calendars, or one source asset adapted cleanly across platforms.

affaan-m/ECC

Multi-platform content distribution across X, LinkedIn, Threads, and Bluesky. Adapts content per platform using content-engine patterns. Never posts identical content cross-platform. Use when the user wants to distribute content across social platforms.

affaan-m/fal-ai-media

Unified media generation via fal.ai MCP — image, video, and audio. Covers text-to-image (Nano Banana), text/image-to-video (Seedance, Kling, Veo 3), text-to-speech (CSM-1B), and video-to-audio (ThinkSound). Use when the user wants to generate images, videos, or audio with AI.

affaan-m/manim-video

日本語翻訳:このファイルは manim-video 用の日本語翻訳が必要です

affaan-m/remotion-video-creation

Remotion のベストプラクティス - React で動画を作成する。3D、アニメーション、音声、字幕、チャート、トランジションなどをカバーするドメイン固有の29のルール。

affaan-m/video-editing

AI-assisted video editing workflows for cutting, structuring, and augmenting real footage. Covers the full pipeline from raw capture through FFmpeg, Remotion, ElevenLabs, fal.ai, and final polish in Descript or CapCut. Use when the user wants to edit video, cut footage, create vlogs, or build video content.

agent-architecture-audit

Full-stack diagnostic for agent and LLM applications. Audits the 12-layer agent stack for wrapper regression, memory pollution, tool discipline failures, hidden repair loops, and rendering corruption. Produces severity-ranked findings with code-first fixes. Essential for developers building agent applications, autonomous loops, or any LLM-powered feature. Use when an agent or LLM feature misbehaves and the failing layer is unknown, or before shipping an agent stack.

agent-eval

Head-to-head comparison of coding agents (Claude Code, Aider, Codex, etc.) on custom tasks with pass rate, cost, time, and consistency metrics. Use when choosing between coding agents, or when a change to an agent setup needs measured pass rate, cost, and time rather than an impression.

agent-harness-construction

Design and optimize AI agent action spaces, tool definitions, and observation formatting for higher completion rates. Use when defining or revising an agent

agentic-engineering

Operate as an agentic engineer using eval-first execution, decomposition, and cost-aware model routing. Use when planning or executing engineering work that agents will carry out end to end.

agentic-os

Build persistent multi-agent operating systems on Claude Code. Covers kernel architecture, specialist agents, slash commands, file-based memory, scheduled automation, and state management without external databases. Use when building a persistent multi-agent system on Claude Code with its own memory, commands, and scheduling.

agent-introspection-debugging

Structured self-debugging workflow for AI agent failures using capture, diagnosis, contained recovery, and introspection reports. Use when an agent run fails and you need a reproducible diagnosis instead of a retry.

agent-payment-x402

Add x402 payment execution to AI agents with per-task budgets, spending controls, and non-custodial wallets. Supports Base through agentwallet-sdk and X Layer through OKX Payments / OKX Agent Payments Protocol. Use when an agent must pay for something itself and needs per-task budgets, spending controls, and a non-custodial wallet.

agent-self-evaluation

Use after completing any non-trivial task. The agent self-rates its output on 5 axes — accuracy, completeness, clarity, actionability, conciseness — with concrete evidence per criterion. Produces a structured 1-5 scorecard with specific improvement suggestions.

agent-sort

Build an evidence-backed ECC install plan for a specific repo by sorting skills, commands, rules, hooks, and extras into DAILY vs LIBRARY buckets using parallel repo-aware review passes. Use when ECC should be trimmed to what a project actually needs instead of loading the full bundle.

ai-first-engineering

Engineering operating model for teams where AI agents generate a large share of implementation output. Use when setting team process, review gates, or ownership rules for a codebase largely written by agents.

ai-regression-testing

Regression testing strategies for AI-assisted development. Sandbox-mode API testing without database dependencies, automated bug-check workflows, and patterns to catch AI blind spots where the same model writes and reviews code. Use when adding regression coverage to AI-assisted code, or when the same model both wrote and reviewed a change.

android-clean-architecture

Clean Architecture patterns for Android and Kotlin Multiplatform projects — module structure, dependency rules, UseCases, Repositories, and data layer patterns. Use when structuring modules, layers, or data flow in an Android or KMP project.

angular-developer

Generates Angular code and provides architectural guidance. Trigger when creating projects, components, or services, or for best practices on reactivity (signals, linkedSignal, resource), forms, dependency injection, routing, SSR, accessibility (ARIA), animations, styling (component styles, Tailwind CSS), testing, or CLI tooling.

Verwandte Skills