Vue.js Composition API

6 Kernkonzepte
Die wichtigsten Konzepte der Vue.js Composition API: setup · ref & reactive · computed · watch & watchEffect · Lifecycle-Hooks · Composables Die Composition API ist der moderne Ansatz in Vue 3, der Logik besser organisiert und wiederverwendbar macht. Sie ist die empfohlene Methode für komplexe Anwendungen und bietet mehr Flexibilität als die Options API.

setup & Reaktive Daten – ref und reactive

setup() · ref · reactive · toRefs
// <script setup> (empfohlen) <script setup> import { ref, reactive } from 'vue'; const count = ref(0); const state = reactive({ name: 'Anna' }); </script>

setup() ist der Einstiegspunkt für die Composition API. ref erzeugt reaktive Referenzen für primitive Werte, reactive für Objekte. <script setup> ist die kompakte Syntax ohne export default.

ref vs reactive

Merkmal ref reactive
Verwendung Primitive Werte (string, number, boolean) Objekte und Arrays
Zugriff .value (im Template automatisch unwrapped) Direkt (kein .value)
Destrukturierung Nicht reaktiv (toRefs verwenden) Nicht reaktiv (toRefs verwenden)
Template Automatisch unwrapped Direkt verwendbar
Beispiele
<script setup>
import { ref, reactive, toRefs } from 'vue';
// Primitive Werte mit ref
const count = ref(0);
const message = ref('Hallo');
const isActive = ref(true);
// Objekte mit reactive
const user = reactive({
name: 'Anna',
age: 30,
address: { city: 'Berlin' }
});
// Zugriff
console.log(count.value); // 0 (ref benötigt .value)
console.log(user.name); // 'Anna' (reactive ohne .value)
// Destrukturierung mit toRefs (reaktiv bleiben)
const { name, age } = toRefs(user);
name.value = 'Max'; // user.name wird aktualisiert
</script>
<template>
<p>{{ count }} - {{ message }} - {{ isActive }}</p>
<p>{{ user.name }} ({{ user.age }})</p>
</template>
Tipp: ref ist die flexiblere Wahl – sie funktioniert für alle Datentypen und kann in Komponenten einfach übergeben werden. reactive ist praktisch für Objekte, aber Vorsicht bei Destrukturierung (mit toRefs reaktiv machen).

computed – Abgeleitete reaktive Werte

computed() · Getter/Setter
import { ref, computed } from 'vue'; const firstName = ref('Anna'); const lastName = ref('Schmidt'); const fullName = computed(() => firstName.value + ' ' + lastName.value);

computed erzeugt einen abgeleiteten reaktiven Wert, der automatisch aktualisiert wird, wenn sich seine Abhängigkeiten ändern. Computed-Werte sind cached – sie werden nur neu berechnet, wenn nötig.

Beispiele
<script setup>
import { ref, computed } from 'vue';
// Einfacher Computed (Getter)
const price = ref(100);
const quantity = ref(2);
const total = computed(() => price.value * quantity.value);
// Computed mit Getter und Setter (Zwei-Wege)
const firstName = ref('Anna');
const lastName = ref('Schmidt');
const fullName = computed({
// Getter
get: () => firstName.value + ' ' + lastName.value,
// Setter
set: (value) => {
const parts = value.split(' ');
firstName.value = parts[0];
lastName.value = parts[1] || '';
}
});
// Computed mit mehreren Abhängigkeiten
const items = ref([
{ name: 'Produkt A', price: 10 },
{ name: 'Produkt B', price: 20 }
]);
const totalPrice = computed(() => {
return items.value.reduce((sum, item) => sum + item.price, 0);
});
</script>
<template>
<input v-model="fullName" />
<p>Gesamt: {{ totalPrice }} €</p>
</template>
Tipp: Computed-Werte sind cached – sie werden nur neu berechnet, wenn sich Abhängigkeiten ändern. Verwenden Sie sie für abgeleitete Werte, nicht für Seiteneffekte (dafür watch verwenden).

watch & watchEffect – Reagieren auf Änderungen

watch · watchEffect · stop
import { ref, watch, watchEffect } from 'vue'; const count = ref(0); watch(count, (newVal, oldVal) => { /* ... */ }); watchEffect(() => { console.log(count.value); });

watch beobachtet spezifische reaktive Quellen und führt einen Callback aus, wenn sich diese ändern. watchEffect führt den Callback sofort aus und trackt automatisch alle verwendeten reaktiven Abhängigkeiten.

watch vs watchEffect

Merkmal watch watchEffect
Abhängigkeiten Explizit deklariert Automatisch getrackt
Ausführung Nur bei Änderung Sofort und bei Änderung
Zugriff auf alte Werte Ja (newVal, oldVal) Nein
Optionen immediate, deep, flush flush
Beispiele
<script setup>
import { ref, watch, watchEffect } from 'vue';
// watch: explizite Abhängigkeit
const searchTerm = ref('');
watch(searchTerm, async (newVal) => {
const results = await fetchData(newVal);
// Ergebnisse aktualisieren
});
// watch mit mehreren Quellen (Array)
const firstName = ref('Anna');
const lastName = ref('Schmidt');
watch([firstName, lastName], ([newFirst, newLast]) => {
console.log(`Name: ${newFirst} ${newLast}`);
});
// watch mit Optionen
watch(user, handleUserChange, {
immediate: true, // Sofort ausführen
deep: true // Tiefe Überwachung (bei Objekten)
});
// watchEffect – automatische Abhängigkeiten
const count = ref(0);
const double = ref(0);
watchEffect(() => {
double.value = count.value * 2; // count wird automatisch getrackt
});
// watchEffect stoppen (cleanup)
const stop = watchEffect(() => { /* ... */ });
// stop() // Aufruf zum Beenden
</script>
<input v-model="searchTerm" />
Tipp: watchEffect ist ideal für Seiteneffekte, die von mehreren reaktiven Quellen abhängen. watch bietet mehr Kontrolle – besonders wenn Sie Zugriff auf alte Werte benötigen oder deep/immediate Optionen nutzen möchten.

Lifecycle-Hooks – onMounted, onUpdated, onUnmounted

onMounted · onUpdated · onUnmounted · onBeforeMount
import { onMounted, onUpdated, onUnmounted } from 'vue'; onMounted(() => { console.log('Komponente gemountet'); });

Lifecycle-Hooks in der Composition API werden als Funktionen importiert und innerhalb von setup() oder <script setup> aufgerufen. Sie ersetzen die Options-API-Hooks wie mounted.

Wichtige Lifecycle-Hooks

Options API Composition API Beschreibung
beforeCreate - Vor Instanzerstellung (setup läuft stattdessen)
created - Nach Instanzerstellung (setup läuft stattdessen)
beforeMount onBeforeMount Vor erstem Rendering
mounted onMounted Nach erstem Rendering
beforeUpdate onBeforeUpdate Vor DOM-Update
updated onUpdated Nach DOM-Update
beforeUnmount onBeforeUnmount Vor Zerstörung
unmounted onUnmounted Nach Zerstörung
Beispiele
<script setup>
import { ref, onMounted, onUpdated, onUnmounted } from 'vue';
const count = ref(0);
let intervalId;
// Nach dem ersten Rendering
onMounted(() => {
console.log('Komponente gemountet');
// API-Aufruf, DOM-Manipulation
intervalId = setInterval(() => {
count.value++;
}, 1000);
});
// Nach jedem DOM-Update
onUpdated(() => {
console.log('DOM aktualisiert');
});
// Beim Zerstören der Komponente
onUnmounted(() => {
clearInterval(intervalId);
console.log('Interval bereinigt');
});
</script>
<template>
<p>Count: {{ count }}</p>
</template>
Tipp: Lifecycle-Hooks in der Composition API müssen synchrone innerhalb von setup() aufgerufen werden (nicht in async Funktionen). Für asynchrone Logik verwenden Sie onMounted mit async/await.

Composables – Wiederverwendbare Logik

useCounter · useFetch · useLocalStorage
// composables/useCounter.js import { ref, computed } from 'vue'; export function useCounter(initialValue = 0) { const count = ref(initialValue); const double = computed(() => count.value * 2); function increment() { count.value++; } return { count, double, increment }; }

Composables sind Funktionen, die reaktive Zustände und Logik kapseln und über mehrere Komponenten hinweg wiederverwendbar machen. Sie sind die moderne Alternative zu Mixins und ermöglichen eine bessere Code-Organisation.

Beispiele
// composables/useFetch.js
import { ref, reactive } from 'vue';
export function useFetch(url) {
const data = ref(null);
const error = ref(null);
const loading = ref(false);
async function fetchData() {
loading.value = true;
try {
const res = await fetch(url);
data.value = await res.json();
} catch (err) {
error.value = err;
} finally {
loading.value = false;
}
}
return { data, error, loading, fetchData };
}
// Verwendung in Komponente
<script setup>
import { useCounter } from './composables/useCounter';
import { useFetch } from './composables/useFetch';
// Counter Composable
const { count, double, increment } = useCounter(5);
// Fetch Composable
const { data, loading, fetchData } = useFetch('https://api.example.com/data');
onMounted(() => {
fetchData();
});
</script>
<template>
<p>Count: {{ count }} (doppelt: {{ double }})</p>
<button @click="increment">+1</button>
<p v-if="loading">Laden...</p>
<pre v-else>{{ data }}</pre>
</template>
Tipp: Composables sind die empfohlene Methode zur Logik-Wiederverwendung in Vue 3. Benennen Sie sie mit use... (z.B. useCounter, useFetch) – das ist eine Konvention und wird von Vue-Erweiterungen unterstützt.

Composition API im Überblick

setup Einstiegspunkt
<script setup>
ref Reaktive Referenzen
.value für Zugriff
reactive Reaktive Objekte
Kein .value
computed Abgeleitete Werte
Cached
watch Seiteneffekte
Explizite Abhängigkeiten
Composables Wiederverwendbare Logik
use* Funktionen

Quick Summary

setup
Einstiegspunkt
ref
Reaktivität
computed
Abgeleitete Werte
watch
Seiteneffekte
onMounted
Lifecycle
use*
Composables
const count = ref(0) · const double = computed(() => count.value * 2) · watch(count, (val) => console.log(val))