Modul 4: Composition API

Options API vs Composition API

Zwei Wege, Vue-Komponenten zu schreiben – und warum die Composition API heute der Standard ist.

Warum gibt es zwei APIs?

Vue 2 bot nur die Options API – ein Objekt mit festen Schlüsseln wie data, methods, computed und watch. Das ist intuitiv für kleine Komponenten, aber bei wachsender Komplexität verteilt sich zusammengehörige Logik über das gesamte Objekt. Vue 3 führte deshalb die Composition API ein: Man gruppiert Code nach Feature statt nach Option.

🛤️

Rails-Vergleich

Stell dir vor, du hast einen Rails-Controller mit vielen before_action-Callbacks, privaten Methoden und Concerns. Die Options API ist wie ein dicker Controller – alles an einem Ort, aber schwer zu überblicken. Die Composition API ist wie das Extrahieren von Service-Objekten und Concerns: Jede Zuständigkeit lebt in ihrer eigenen Einheit.

Dieselbe Komponente – zwei Stile

Hier ist ein einfacher Counter in beiden APIs. Achte darauf, wie sich die Struktur unterscheidet:

Options API

CounterOptions.vue
<template>
  <button @click="increment">{{ count }} (× {{ doubled }})</button>
</template>
<script>
export default {
  data() {
    return { count: 0 }
  },
  computed: {
    doubled() {
      return this.count * 2
    }
  },
  methods: {
    increment() {
      this.count++
    }
  }
}
</script>

Composition API (script setup)

CounterComposition.vue
<template>
  <button @click="increment">{{ count }} (× {{ doubled }})</button>
</template>
<script setup>
import { ref, computed } from 'vue'
const count = ref(0)
const doubled = computed(() => count.value * 2)
function increment() {
  count.value++
}
</script>
💡

Beobachte den Unterschied

In der Options API sind data, computed und methods in getrennten Blöcken. In der Composition API stehen count, doubled und increment direkt zusammen – gruppiert nach Feature, nicht nach Typ.

Vorteile der Composition API

🔷 Besseres TypeScript

Volle Typ-Inferenz ohne Workarounds. ref(0) wird automatisch als Ref<number> erkannt.

📦 Code-Organisation

Zusammengehörige Logik bleibt zusammen, egal ob State, Computed oder Watcher.

♻️ Wiederverwendbarkeit

Logik lässt sich als Composable extrahieren und in mehreren Komponenten nutzen – sauberer als Mixins.

🌳 Besseres Tree-Shaking

Nur importierte Funktionen landen im Bundle. Die Options API bringt immer alles mit.

Wachsende Komplexität: Der entscheidende Punkt

Bei kleinen Komponenten ist der Unterschied gering. Sobald eine Komponente aber mehrere Features verwaltet – z.B. Suche, Paginierung und Sortierung – zeigt sich die Stärke der Composition API. Statt den Code über data, computed, methods und watch zu verteilen, kann man drei saubere Composables schreiben:

UserList.vue
<script setup>
// Jedes Feature ist ein eigenes Composable
const { query, results } = useSearch()
const { page, perPage, total } = usePagination()
const { sortBy, sortDir, toggle } = useSorting()
// Alles zusammen nutzen
const users = computed(() =>
  sortItems(results.value, sortBy.value, sortDir.value)
    .slice((page.value - 1) * perPage.value, page.value * perPage.value)
)
</script>
🛤️

Rails-Vergleich: Concerns vs Composables

In Rails nutzt du ActiveSupport::Concern oder Mixins, um Logik aus einem fetten Model oder Controller herauszuziehen. Composables sind Vues Äquivalent – aber ohne die Probleme von Mixins (Namenskollisionen, unklare Herkunft). Jeder Import ist explizit und nachvollziehbar.

Wann die Options API noch in Ordnung ist

Die Options API ist nicht deprecated! Sie wird weiterhin vollständig unterstützt. In diesen Fällen ist sie eine valide Wahl:

  • Kleine, einfache Komponenten – wenn die Logik in 30 Zeilen passt
  • Bestehende Vue-2-Projekte – Migration schrittweise statt Big Bang
  • Einsteiger im Team – die Options API hat eine flachere Lernkurve
  • Prototypen – schnell etwas hinwerfen ohne viel Struktur-Overhead
ℹ️

Beide APIs können im selben Projekt koexistieren. Du musst dich nicht für eine entscheiden – nutze die Composition API für komplexe Logik und die Options API, wo sie ausreicht.

Live-Demo: Composition API Counter

Counter mit Composition API
Interaktiv
0

Doppelt: 0

Migrationspfad: Schritt für Schritt

Du musst nicht alles auf einmal umschreiben. Hier ist ein pragmatischer Plan:

1.

Neue Komponenten in Composition API schreiben

Bestehender Code bleibt unverändert.

2.

Mixins durch Composables ersetzen

Das ist der größte Quick-Win für Code-Qualität.

3.

Komplexe Komponenten bei Änderungen migrieren

Wenn du sowieso refactorst, gleich auf Composition API umstellen.

4.

Einfache Komponenten bei Bedarf umstellen

Kein Druck – die Options API bleibt unterstützt.

Mixin → Composable Migration
// ❌ Vorher: Mixin (implizit, Namenskollisionen möglich)
const SearchMixin = {
  data() {
    return { query: '', results: [] }
  },
  methods: {
    async search() {
      this.results = await api.search(this.query)
    }
  }
}
// ✅ Nachher: Composable (explizit, typsicher)
function useSearch() {
  const query = ref('')
  const results = ref([])
  async function search() {
    results.value = await api.search(query.value)
  }
  return { query, results, search }
}
⚠️

Achtung bei Mixins

Vue-3-Mixins funktionieren noch, aber sie haben die gleichen Probleme wie in Vue 2: Namenskollisionen, implizite Abhängigkeiten und schwer nachvollziehbarer Datenfluss. Composables lösen all diese Probleme.

Zusammenfassung

AspektOptions APIComposition API
OrganisationNach Typ (data, methods …)Nach Feature
TypeScriptEingeschränktVolle Unterstützung
WiederverwendungMixins (problematisch)Composables (sauber)
LernkurveFlacherEtwas steiler
Rails-ÄquivalentFat Controller / ConcernsService Objects / POROs