Appearance
Kapitel 21: Composition API (Teil 1) - Einführung
📙 Lernziel: Warum Composition API? Unterschied zu Options API verstehen!
21.1 Was ist Composition API?
Composition API ist ein neuer Weg, um Vue-Komponenten zu erstellen (Vue 3+).
Zwei Wege in Vue 3:
- Options API (Vue 2 Stil) -
data(),methods,computed, etc. - Composition API (Vue 3 modern) -
setup()oder<script setup>
Vergleich:
| Merkmal | Options API | Composition API |
|---|---|---|
| Lernkurve | Einfacher (für Anfänger) | Steiler (für Fortgeschrittene) |
| Logik-Wiederverwendung | Mixins (schlecht) | Composables (gut) |
| TypeScript | Schwierig | Einfach |
| Logik-Organisation | Nach Optionen | Nach Logik-Funktionen |
21.2 Options API Beispiel
Options API (Vue 2 Stil):
vue
<script>
export default {
// Daten
data() {
return {
count: 0,
message: 'Hallo'
}
},
// Methoden
methods: {
increment() {
this.count++
},
updateMessage() {
this.message = 'Aktualisiert!'
}
},
// Computed Properties
computed: {
doubleCount() {
return this.count * 2
}
},
// Watcher
watch: {
count(newValue, oldValue) {
console.log(`Count: ${oldValue} → ${newValue}`)
}
},
// Lebenszyklus
mounted() {
console.log('Komponente gemountet!')
}
}
</script>
<template>
<div>
<p>Zähler: {{ count }}</p>
<p>Doppelt: {{ doubleCount }}</p>
<p>{{ message }}</p>
<button @click="increment">Erhöhen</button>
<button @click="updateMessage">Nachricht ändern</button>
</div>
</template>Probleme:
- ❌ Logik ist nach Optionen organisiert, nicht nach Funktionen
- ❌ Bei großen Komponenten schwer zu warten
- ❌ Logik-Wiederverwendung mit Mixins ist fehleranfällig
21.3 Composition API Beispiel (<script setup>)
Composition API (<script setup>):
vue
<script setup>
import { ref, computed, watch, onMounted } from 'vue'
// Daten (reaktiv)
const count = ref(0)
const message = ref('Hallo')
// Methoden
const increment = () => {
count.value++
}
const updateMessage = () => {
message.value = 'Aktualisiert!'
}
// Computed Properties
const doubleCount = computed(() => count.value * 2)
// Watcher
watch(count, (newValue, oldValue) => {
console.log(`Count: ${oldValue} → ${newValue}`)
})
// Lebenszyklus
onMounted(() => {
console.log('Komponente gemountet!')
})
</script>
<template>
<div>
<p>Zähler: {{ count }}</p>
<p>Doppelt: {{ doubleCount }}</p>
<p>{{ message }}</p>
<button @click="increment">Erhöhen</button>
<button @click="updateMessage">Nachricht ändern</button>
</div>
</template>Vorteile:
- ✅ Logik ist nach Funktionen organisiert
- ✅ Bessere Lesbarkeit bei großen Komponenten
- ✅ Logik-Wiederverwendung mit Composables
- ✅ Bessere TypeScript-Unterstützung
21.4 setup() Funktion (Alternative)
setup() Funktion (ohne <script setup>):
vue
<script>
import { ref, computed, watch, onMounted } from 'vue'
export default {
setup() {
// Daten
const count = ref(0)
const message = ref('Hallo')
// Methoden
const increment = () => {
count.value++
}
const updateMessage = () => {
message.value = 'Aktualisiert!'
}
// Computed
const doubleCount = computed(() => count.value * 2)
// Watcher
watch(count, (newValue, oldValue) => {
console.log(`Count: ${oldValue} → ${newValue}`)
})
// Lebenszyklus
onMounted(() => {
console.log('Komponente gemountet!')
})
// Alles zurückgeben, was im Template genutzt werden soll
return {
count,
message,
increment,
updateMessage,
doubleCount
}
}
}
</script>
<template>
<div>
<p>Zähler: {{ count }}</p>
<p>Doppelt: {{ doubleCount }}</p>
<p>{{ message }}</p>
<button @click="increment">Erhöhen</button>
</div>
</template><script setup> vs setup():
- ✅
<script setup>ist kürzer (keinreturnnötig) - ✅
<script setup>ist die empfohlene Schreibweise
21.5 Composables (Logik-Wiederverwendung)
Composables sind Funktionen, die Composition API nutzen, um Logik wiederzuverwenden.
Beispiel: useCounter.js (Composable)
javascript
// composables/useCounter.js
import { ref } from 'vue'
export function useCounter() {
const count = ref(0)
const increment = () => {
count.value++
}
const decrement = () => {
count.value--
}
const reset = () => {
count.value = 0
}
return {
count,
increment,
decrement,
reset
}
}Verwendung in Komponente:
vue
<script setup>
import { useCounter } from '../composables/useCounter.js'
// Logik wiederverwenden
const { count, increment, decrement, reset } = useCounter()
</script>
<template>
<div>
<p>Zähler: {{ count }}</p>
<button @click="increment">+</button>
<button @click="decrement">-</button>
<button @click="reset">Zurücksetzen</button>
</div>
</template>Vorteile gegenüber Mixins:
- ✅ Explizite Abhängigkeiten (keine Namenskonflikte)
- ✅ Bessere TypeScript-Unterstützung
- ✅ Einfacher zu testen
21.6 Übung: Options API zu Composition API migrieren
Aufgabe: Migriere diese Options API Komponente zu Composition API (<script setup>).
Options API (vorher):
vue
<script>
export default {
data() {
return {
todos: [],
newTodo: ''
}
},
methods: {
addTodo() {
if (this.newTodo.trim() !== '') {
this.todos.push({
id: Date.now(),
text: this.newTodo,
done: false
})
this.newTodo = ''
}
},
removeTodo(id) {
this.todos = this.todos.filter(todo => todo.id !== id)
}
},
computed: {
doneCount() {
return this.todos.filter(todo => todo.done).length
}
}
}
</script>
<template>
<div>
<input v-model="newTodo" @keyup.enter="addTodo" />
<button @click="addTodo">Hinzufügen</button>
<ul>
<li v-for="todo in todos" :key="todo.id">
<input type="checkbox" v-model="todo.done" />
<span :style="{ textDecoration: todo.done ? 'line-through' : 'none' }">
{{ todo.text }}
</span>
<button @click="removeTodo(todo.id)">Löschen</button>
</li>
</ul>
<p>Erledigt: {{ doneCount }}</p>
</div>
</template>Composition API (nachher - Lösung):
vue
<script setup>
import { ref, computed } from 'vue'
const todos = ref([])
const newTodo = ref('')
const addTodo = () => {
if (newTodo.value.trim() !== '') {
todos.value.push({
id: Date.now(),
text: newTodo.value,
done: false
})
newTodo.value = ''
}
}
const removeTodo = (id) => {
todos.value = todos.value.filter(todo => todo.id !== id)
}
const doneCount = computed(() => {
return todos.value.filter(todo => todo.done).length
})
</script>
<template>
<div>
<input v-model="newTodo" @keyup.enter="addTodo" />
<button @click="addTodo">Hinzufügen</button>
<ul>
<li v-for="todo in todos" :key="todo.id">
<input type="checkbox" v-model="todo.done" />
<span :style="{ textDecoration: todo.done ? 'line-through' : 'none' }">
{{ todo.text }}
</span>
<button @click="removeTodo(todo.id)">Löschen</button>
</li>
</ul>
<p>Erledigt: {{ doneCount }}</p>
</div>
</template>✅ Zusammenfassung
In diesem Kapitel hast du gelernt:
- ✅ Was Composition API ist
- ✅ Unterschied zwischen Options API und Composition API
- ✅
<script setup>Syntax - ✅
setup()Funktion (Alternative) - ✅ Composables (Logik-Wiederverwendung)
- ✅ Options API zu Composition API migrieren
🎯 Nächster Schritt: In Kapitel 22 lernst du reaktive Grundlagen (ref() und reactive())!
← Zurück zu Kapitel 20: Lebenszyklus-HooksWeiter zu Kapitel 22: Reaktive Grundlagen →
