Modul 2: Vue Grundlagen

Reaktivität

Das Herzstück von Vue — wie Datenänderungen automatisch die Oberfläche aktualisieren

Was ist Reaktivität?

Reaktivität ist das zentrale Konzept in Vue.js. Es bedeutet: Wenn sich Daten ändern, aktualisiert sich die Oberfläche automatisch. Kein manuelles DOM-Update, kein innerHTML, kein jQuery — Vue erledigt das für dich.

Als Rails-Entwickler kennst du das Problem: Du änderst eine Instance-Variable im Controller, aber die Seite zeigt erst nach einem kompletten Page-Reload die neuen Daten. In Vue passiert das Update sofort und automatisch.

🛤️

Rails-Vergleich: Instance Variables vs Refs

In Rails definierst du Daten im Controller mit @variable und übergibst sie an die View. Das ist ein Einweg-Prozess: Controller → View → fertig. Änderungen erfordern einen neuen Request.

Rails: ProductsController
# Rails: Einmaliger Datenfluss
class ProductsController < ApplicationController
  def show
    @product = Product.find(params[:id])
    @preis_mit_mwst = @product.preis * 1.19
    # Nach dem Rendern ist Schluss — keine Reaktivität
  end
end
Vue: Reaktive Daten
<!-- Vue: Daten sind reaktiv — Änderungen = automatische Updates -->
<script setup>
import { ref, computed } from 'vue'

const preis = ref(29.99)
const preisMitMwst = computed(() => preis.value * 1.19)

// Ändert sich preis → preisMitMwst aktualisiert sich automatisch!
</script>

ref() — Reaktive Einzelwerte

ref() ist die häufigste Art, reaktive Daten in Vue zu erstellen. Du umschließt einen Wert mit ref(), und Vue verfolgt alle Änderungen daran.

RefBeispiel.vue
<script setup>
import { ref } from 'vue'

// Verschiedene Typen mit ref()
const zaehler = ref(0)           // number
const name = ref('Anna')         // string
const istSichtbar = ref(true)    // boolean
const liste = ref([1, 2, 3])    // array
const benutzer = ref({           // object
  name: 'Max',
  alter: 28
})

// Im Script: .value ist nötig!
function erhoehen() {
  zaehler.value++
  console.log(zaehler.value) // 1
}

// Array-Methoden funktionieren
function hinzufuegen() {
  liste.value.push(4)
}
</script>

<template>
  <!-- Im Template: KEIN .value nötig! Vue unwrapped automatisch -->
  <p>Zähler: {{ zaehler }}</p>
  <p>Name: {{ name }}</p>
  <button @click=\"erhoehen\">+1</button>
</template>
⚠️

Die .value-Falle

Der häufigste Anfängerfehler: .value im Script vergessen!

script setup
const count = ref(0)

// ❌ FALSCH: Ändert nicht den reaktiven Wert
count = 5

// ✅ RICHTIG: Ändert den reaktiven Wert
count.value = 5

// ❌ FALSCH im Script
console.log(count) // Ref-Objekt, nicht der Wert

// ✅ RICHTIG im Script
console.log(count.value) // 5

Merkregel: Im <script> brauchst du .value, im <template> nicht.

reactive() — Reaktive Objekte

reactive() macht ein ganzes Objekt reaktiv — ohne .value. Es funktioniert nur mit Objekten, Arrays und Maps/Sets.

ReactiveBeispiel.vue
<script setup>
import { reactive } from 'vue'

const formular = reactive({
  vorname: '',
  nachname: '',
  email: '',
  agb: false
})

// Kein .value nötig — direkter Zugriff!
function absenden() {
  console.log(formular.vorname)
  console.log(formular.email)
}

// Eigenschaften direkt ändern
function zuruecksetzen() {
  formular.vorname = ''
  formular.nachname = ''
  formular.email = ''
  formular.agb = false
}
</script>

<template>
  <input v-model=\"formular.vorname\" placeholder=\"Vorname\">
  <input v-model=\"formular.nachname\" placeholder=\"Nachname\">
  <input v-model=\"formular.email\" type=\"email\" placeholder=\"E-Mail\">
  <label>
    <input v-model=\"formular.agb\" type=\"checkbox\"> AGB akzeptiert
  </label>
</template>

ref() vs reactive() — Wann was verwenden?

Vergleich
// ref() — für primitive Werte und wenn du flexibel bleiben willst
const count = ref(0)           // ✅ Primitive
const user = ref({ name: '' }) // ✅ Auch für Objekte möglich
count.value++                  // .value nötig im Script

// reactive() — für Objekte, wenn du .value vermeiden willst
const form = reactive({ name: '', email: '' })
form.name = 'Max'              // Kein .value nötig

// ⚠️ reactive() hat Einschränkungen:
const count2 = reactive(0)     // ❌ Geht NICHT mit Primitiven
let form2 = reactive({ a: 1 })
form2 = reactive({ a: 2 })     // ❌ Verliert Reaktivität!
💡

Empfehlung: Verwende ref() als Standard

Die offizielle Vue-Empfehlung und die gängige Praxis in der Community: Verwende ref() für alles. Es ist konsistenter und hat keine der Einschränkungen von reactive(). Verwende reactive() nur, wenn du explizit ein Formularobjekt oder ähnliches gruppieren möchtest und .value vermeiden willst.

computed() — Abgeleitete Werte

computed() erstellt einen Wert, der automatisch aus anderen reaktiven Werten berechnet wird. Ändert sich eine Abhängigkeit, wird der computed-Wert neu berechnet.

ComputedBeispiel.vue
<script setup>
import { ref, computed } from 'vue'

const vorname = ref('Max')
const nachname = ref('Mustermann')

// Computed: Wird automatisch aktualisiert
const vollName = computed(() => {
  return \`

const codeExample8 = 
ℹ️

computed() vs Methode — Was ist der Unterschied?

Eine Methode wird bei jedem Render erneut ausgeführt. Ein computed()-Wert wird gecached und nur neu berechnet, wenn sich eine seiner Abhängigkeiten ändert. Bei aufwändigen Berechnungen ist computed() deshalb deutlich performanter.

Cache-Vergleich

Wie Vue Abhängigkeiten verfolgt

Vue verwendet ein cleveres System namens Dependency Tracking:

  1. Wenn ein computed() oder ein Template ausgeführt wird, merkt sich Vue, welche reaktiven Werte gelesen werden.
  2. Diese werden als Abhängigkeiten registriert.
  3. Ändert sich eine Abhängigkeit, wird nur das erneut berechnet, was davon abhängt — nicht die ganze Seite.
DependencyTracking.ts
const vorname = ref('Max')
const nachname = ref('Mustermann')
const alter = ref(28)

// Vue merkt sich: vollName hängt von vorname UND nachname ab
const vollName = computed(() => {
  return vorname.value + ' ' + nachname.value
  // alter.value wird NICHT gelesen → keine Abhängigkeit
})

// Nur diese Änderungen lösen ein Update von vollName aus:
vorname.value = 'Anna'     // ✅ Trigger
nachname.value = 'Schmidt' // ✅ Trigger
alter.value = 30           // ❌ Kein Trigger für vollName
🛤️

Rails-Vergleich: Kein Äquivalent!

Rails hat kein Konzept von Dependency Tracking. Die nächste Analogie wären Active Record Callbacks oder after_save-Hooks — aber die sind manuell definiert. Vue erkennt Abhängigkeiten automatisch zur Laufzeit.

Interaktive Demo

Klicke auf die Buttons und beobachte, wie sich alle abgeleiteten Werte automatisch aktualisieren:

Reaktivität Live-Demo: Zähler mit computed()
Interaktiv

count

ref(0)

doubled

computed(() => count * 2)

isEven

false ✗

computed(() => count % 2 === 0)

Zusammenfassung:

Der Zähler steht auf . Das ist eine ungerade Zahl. Das Doppelte ist .

Zusammenfassung

💡

Das Wichtigste auf einen Blick

  • ref() — Macht jeden Wert reaktiv (.value im Script nötig)
  • reactive() — Macht Objekte reaktiv (kein .value, aber Einschränkungen)
  • computed() — Abgeleitete Werte, die automatisch gecached werden
  • Vue verfolgt Abhängigkeiten automatisch — du musst nichts konfigurieren
  • Empfehlung: Verwende ref() als Standard für alles