Appearance
Kapitel 22: Composition API (Teil 2) - Reaktive Grundlagen
📙 Lernziel: ref() und reactive() meistern - reaktive Daten in Vue 3!
22.1 Was ist Reaktivität?
Reaktivität bedeutet: Wenn sich Daten ändern, wird die Benutzeroberfläche automatisch aktualisiert.
Beispiel (ohne Reaktivität):
javascript
let count = 0
count++ // UI wird NICHT aktualisiertBeispiel (mit Reaktivität - Vue 3):
vue
<script setup>
import { ref } from 'vue'
const count = ref(0)
count.value++ // UI wird AUTOMATISCH aktualisiert!
</script>
<template>
<p>{{ count }}</p>
</template>22.2 ref() - Für primitive Werte
ref() macht primitive Werte (number, string, boolean) reaktiv.
Syntax:
javascript
import { ref } from 'vue'
const variable = ref(initialWert)Beispiele:
vue
<script setup>
import { ref } from 'vue'
// Primitive Werte
const count = ref(0) // number
const message = ref('Hallo') // string
const isVisible = ref(true) // boolean
const todoList = ref([]) // array
const user = ref({}) // object
// Zugriff und Änderung (mit .value!)
console.log(count.value) // 0
count.value++
console.log(count.value) // 1
message.value = 'Vue 3 ist toll!'
isVisible.value = false
todoList.value.push('Neue Aufgabe')
user.value = { name: 'Max', age: 25 }
</script>
<template>
<p>{{ count }}</p>
<p>{{ message }}</p>
<p>{{ isVisible }}</p>
</template>Wichtig:
- ✅ Im
<script>: Immer.valueverwenden! - ✅ Im
<template>: Nie.valueverwenden (Vue macht das automatisch)!
22.3 reactive() - Für Objekte
reactive() macht Objekte und Arrays reaktiv (tiefgreifend).
Syntax:
javascript
import { reactive } from 'vue'
const objekt = reactive({ ... })Beispiele:
vue
<script setup>
import { reactive } from 'vue'
// Objekte
const state = reactive({
count: 0,
message: 'Hallo',
isVisible: true
})
// Zugriff und Änderung (OHNE .value!)
console.log(state.count) // 0
state.count++
console.log(state.count) // 1
state.message = 'Vue 3 ist toll!'
state.isVisible = false
// Arrays
const todos = reactive(['Lernen', 'Sport'])
todos.push('Einkaufen')
todos[0] = 'Vue 3 lernen'
// Verschachtelte Objekte (auch reaktiv!)
const user = reactive({
name: 'Max',
address: {
city: 'Berlin',
street: 'Hauptstraße'
}
})
user.address.city = 'München' // Auch reaktiv!
</script>
<template>
<p>{{ state.count }}</p>
<p>{{ state.message }}</p>
<ul>
<li v-for="todo in todos" :key="todo">{{ todo }}</li>
</ul>
</template>Vorteile von reactive():
- ✅ Kein
.valuenötig - ✅ Tiefgreifende Reaktivität (auch verschachtelte Objekte)
22.4 ref() vs reactive() - Wann was nutzen?
Empfehlungen:
| Situation | Empfehlung | Beispiel |
|---|---|---|
| Primitive Werte (number, string, boolean) | ref() | const count = ref(0) |
| Einfache Objekte/Arrays | reactive() | const state = reactive({ ... }) |
| Komplextes State-Objekt | reactive() | const state = reactive({ user: {...}, posts: [...] }) |
| Einzelne Werte (auch Objekte) | ref() | const user = ref({ ... }) |
Migrierung zwischen ref() und reactive():
vue
<script setup>
import { ref, reactive, toRefs } from 'vue'
// ref() zu reactive()
const userRef = ref({ name: 'Max', age: 25 })
const userReactive = reactive(userRef.value)
// reactive() zu ref() (mit toRefs() - später)
const state = reactive({ count: 0, message: 'Hallo' })
const stateAsRefs = toRefs(state) // Macht jedes Property zu ref()
</script>Meinung der Vue-Community:
- Viele Entwickler nutzen nur
ref()(einheitlicher) reactive()ist nützlich für komplexe State-Objekte
22.5 Reaktivität "Lost" (Verlust der Reaktivität)
Problem: Reaktivität geht verloren, wenn du Eigenschaften destrukturierst.
❌ Falsch (Reaktivität verloren):
vue
<script setup>
import { reactive } from 'vue'
const state = reactive({ count: 0, message: 'Hallo' })
// ❌ Destrukturierung (Reaktivität verloren!)
const { count, message } = state
count++ // UI wird NICHT aktualisiert!
</script>
<template>
<p>{{ count }}</p> <!-- Ändert sich nicht! -->
</template>✅ Richtig (mit toRefs()):
vue
<script setup>
import { reactive, toRefs } from 'vue'
const state = reactive({ count: 0, message: 'Hallo' })
// ✅ toRefs() (Reaktivität erhalten!)
const { count, message } = toRefs(state)
count.value++ // UI wird aktualisiert!
</script>
<template>
<p>{{ count }}</p> <!-- Ändert sich! -->
</template>Oder einfach state. verwenden:
vue
<script setup>
import { reactive } from 'vue'
const state = reactive({ count: 0, message: 'Hallo' })
// ✅ Einfach state. verwenden
state.count++ // UI wird aktualisiert!
</script>
<template>
<p>{{ state.count }}</p> <!-- Ändert sich! -->
</template>22.6 toRef() und toRefs()
toRef() - Macht eine einzelne Eigenschaft reaktiv (Ref).
toRefs() - Macht alle Eigenschaften reaktiv (Refs).
Beispiele:
vue
<script setup>
import { reactive, toRef, toRefs } from 'vue'
const state = reactive({ count: 0, message: 'Hallo' })
// toRef() (einzelne Eigenschaft)
const countRef = toRef(state, 'count')
countRef.value++ // state.count wird auch aktualisiert!
// toRefs() (alle Eigenschaften)
const { count, message } = toRefs(state)
count.value++ // state.count wird auch aktualisiert!
message.value = 'Vue 3' // state.message wird auch aktualisiert!
</script>Anwendungsfall (Composables):
javascript
// composables/useCounter.js
import { reactive, toRefs } from 'vue'
export function useCounter() {
const state = reactive({
count: 0,
step: 1
})
const increment = () => {
state.count += state.step
}
const decrement = () => {
state.count -= state.step
}
// toRefs() damit Destrukturierung möglich ist
return {
...toRefs(state),
increment,
decrement
}
}Verwendung:
vue
<script setup>
import { useCounter } from '../composables/useCounter.js'
// ✅ Destrukturierung (dank toRefs() reaktiv!)
const { count, step, increment, decrement } = useCounter()
</script>
<template>
<p>Zähler: {{ count }}</p>
<button @click="increment">+</button>
<button @click="decrement">-</button>
</template>22.7 Übung: Counter mit ref() und reactive()
Aufgabe: Erstelle einen Counter, der ref() und reactive() nutzt.
Lösung:
vue
<script setup>
import { ref, reactive } from 'vue'
// Mit ref()
const count = ref(0)
// Mit reactive()
const state = reactive({
step: 1,
min: 0,
max: 100
})
const increment = () => {
if (count.value < state.max) {
count.value += state.step
}
}
const decrement = () => {
if (count.value > state.min) {
count.value -= state.step
}
}
const reset = () => {
count.value = 0
}
</script>
<template>
<div class="counter">
<h2>Zähler: {{ count }}</h2>
<div>
<button @click="decrement">-</button>
<span>{{ count }}</span>
<button @click="increment">+</button>
</div>
<div>
<label>Schritt: <input type="number" v-model="state.step" min="1" max="10" /></label>
<label>Minimum: <input type="number" v-model="state.min" /></label>
<label>Maximum: <input type="number" v-model="state.max" /></label>
</div>
<button @click="reset">Zurücksetzen</button>
</div>
</template>
<style scoped>
.counter {
border: 1px solid #42b883;
border-radius: 8px;
padding: 20px;
max-width: 400px;
margin: 0 auto;
}
.counter div {
margin: 10px 0;
}
button {
padding: 5px 15px;
margin: 0 5px;
background: #42b883;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
}
label {
display: block;
margin: 5px 0;
}
</style>✅ Zusammenfassung
In diesem Kapitel hast du gelernt:
- ✅ Was Reaktivität ist
- ✅
ref()für primitive Werte nutzen - ✅
reactive()für Objekte/Arrays nutzen - ✅ Unterschied zwischen
ref()undreactive() - ✅ Reaktivität "Lost" vermeiden (mit
toRefs()) - ✅
toRef()undtoRefs()nutzen - ✅ Praxis: Counter mit
ref()undreactive()
🎯 Nächster Schritt: In Kapitel 23 lernst du computed() und watch() in Composition API!
← Zurück zu Kapitel 21: Composition API EinführungWeiter zu Kapitel 23: computed() & watch() →
