Reaktive Daten

Reaktivität ist das grundlegendste Konzept in Vue3.

In diesem Kapitel wirst du verstehen, was Reaktivität ist, und lernen,refundreactivezu verwenden, um Daten zu verwalten und eine Kategoriefilterfunktion zu implementieren.


Was ist Reaktivität?

Reaktivität bedeutet:Wenn sich Daten ändern, aktualisiert sich die Seite automatisch.。

Der traditionelle JS-Ansatz sieht so aus: Nach dem Ändern einer Variablen musst du das DOM manuell aktualisieren.

Das reaktive System von Vue3 verfolgt Datenänderungen automatisch und benachrichtigt die Ansicht, sich zu aktualisieren – du musst dich nur um die Daten kümmern, nicht um das DOM.

Beispiel

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

// Von ref umhüllte Variablen sind reaktiv
const count = ref(0)

// Nach dem Ändern von count wird {{ count }} im Template automatisch aktualisiert
function increment() {
count.value++ // Hinweis: In JS benötigt man .value für den Zugriff
}
</script>

<template>
  <p>Klickzähler: {{ count }}</p>
  <!-- Im Template automatisch entpackt, kein .value nötig -->
  <button @click="increment">+1</button>
</template>

Nachdem du auf den Button geklickt hast, ändert sich die auf der Seite angezeigte Zahl automatisch — das ist Reaktivität.

Du musst nichts schreibendocument.querySelectoroderinnerHTMLum die Seite zu aktualisieren.


ref — Umgang mit primitiven Typen

refist die am häufigsten verwendete reaktive API in Vue3, geeignet zum Umhüllen von Daten primitiver Typen.

Primitive Typen umfassen: Strings, Zahlen, Booleans, null, undefined.

Syntax

Beispiel

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

// Eine Ref erstellen
const name = ref('EXAMPLE') // String
const age = ref(18) // Number
const isVip = ref(false) // Boolean

// .value lesen
console.log(name.value) // "EXAMPLE"
console.log(age.value) // 18

// .value ändern
name.value = 'Hello EXAMPLE'
age.value++
isVip.value = !isVip.value
</script>

<template>
  <p>Name: {{ name }}</p>
  <!-- In Templates wird ref automatisch entpackt, kein .value nötig -->
  <p>Alter: {{ age }}</p>
  <p>VIP:{{ isVip }}</p>
</template>

Das Wichtigste, das man sich merken sollte:Im JS-Code benötigt man .value, in Templates jedoch nicht.Das ist der häufigste Fehler, den Anfänger machen.


reactive — Umgang mit Objekten und Arrays

reactiveGeeignet zum Umhüllen von Referenztyp-Daten wie Objekten oder Arrays.

Anders als ref benötigt reactive nicht.value.value, und du kannst direkt auf Eigenschaften zugreifen.

Beispiel

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

// Ein Objekt mit reactive umhüllen
const user = reactive({
name: 'Xiaoming',
  age: 20,
hobbies: ['programming', 'running']
})

// Direkt zugreifen und ändern, kein .value erforderlich
console.log(user.name) // "Xiao Ming"
user.name = 'Xiao Hua' // Reaktives Update
user.hobbies.push('reading') // Array-Operationen sind ebenfalls reaktiv
</script>

<template>
  <p>Name: {{ user.name }}</p>
  <p>Alter: {{ user.age }}</p>
  <ul>
    <li v-for="(hobby, index) in user.hobbies" :key="index">
      {{ hobby }}
    </li>
  </ul>
</template>

Zwei Einschränkungen von reactive

EinschränkungBeschreibungLösung
Kann nur Objekttypen umschließenPrimitive Typen wie Zeichenketten, Zahlen können nicht übergeben werdenVerwende ref für primitive Typen
Kann nicht als Ganzes ersetzt werdenDas gesamte Objekt kann nicht einem neuen Objekt zugewiesen werdenVerwende Object.assign() oder wechsle zu ref

Beispiel

import { reactive, ref } from 'vue'

// Fehler: Das reaktive Objekt kann nicht als Ganzes ersetzt werden
const state = reactive({ count: 0 })
// state = { count: 1 } // Das funktioniert nicht, die Reaktivität geht verloren

// Richtiger Ansatz 1: Eigenschaften ändern, statt das Ganze zu ersetzen
state.count = 1

// Korrekter Ansatz 2: Verwende ref, um das Objekt zu umschließen (ref ermöglicht das Ersetzen des gesamten Objekts)
const stateRef = ref({ count: 0 })
stateRef.value = { count: 1 }  // Es funktioniert! Weil der .value von ref ersetzt werden kann

ref vs reactive: Wann welches verwenden

SzenarioEmpfehlungBeispiel
Einzelner String/Number/Booleanrefconst name = ref('小明')
Einzelnes Arrayrefconst list = ref([])
Einzelnes ObjektSowohl ref als auch reactive funktionierenconst user = ref({})
Mehrere nicht zusammenhängende ZuständeVerwende ref für jedenEin ref pro Zeile
Eine Gruppe stark zusammenhängender Zuständereactivez. B. Formulardaten, Konfigurationssammlung

Die gängigste Praxis in der tatsächlichen Entwicklung ist:Immer ref verwenden, auch für Objekte und Arrays。

Dadurch bleibt der Code-Stil konsistent, und du musst dein mentales Modell nicht zwischen ref und reactive wechseln.

Die folgenden Kapitel dieses Tutorials verwenden einheitlich ref, um den gesamten Zustand zu verwalten. Wenn Stellen auftreten, die.valuereactive erfordern, werden diese Stellen besonders gekennzeichnet.


computed — Berechnete Eigenschaften

computedist „aus vorhandenen Daten berechnete Daten“.

Es hat zwei Kernfunktionen:Caching——wenn sich Abhängigkeiten nicht ändern, wird nicht neu berechnet;Automatische Nachverfolgung——wenn sich Abhängigkeiten ändern, wird automatisch aktualisiert.

Beispiel

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

const articles = ref([
Erste Schritte mit Vue3
{ id: 2, title: 'Promise ausführlich erklärt', category: 'JavaScript' },
Grid-Layout
  { id: 4, title: 'Composition API', category: 'Vue' }
])

const activeCategory = ref('All')

// computed filtert Artikel basierend auf activeCategory
const filteredArticles = computed(() => {
if (activeCategory.value === 'All') {
    return articles.value
  }
  return articles.value.filter(a => a.category === activeCategory.value)
})

// computed kann auch für Statistiken verwendet werden
const totalCount = computed(() => articles.value.length)
const filteredCount = computed(() => filteredArticles.value.length)
</script>

<template>
  <p>Insgesamt {{ totalCount }} Artikel, derzeit werden {{ filteredCount }} angezeigt</p>

  <!-- Kategorie-Schaltflächen -->
  <button @click=activeCategory = 'All'>Alle</button>
  <button @click="activeCategory = 'Vue'">Vue</button>
  <button @click="activeCategory = 'JavaScript'">JavaScript</button>
  <button @click="activeCategory = 'CSS'">CSS</button>

  <!-- Gefilterte Artikelliste -->
  <div v-for="article in filteredArticles" :key="article.id">
    <h3>{{ article.title }}</h3>
    <span>{{ article.category }}</span>
  </div>
</template>

Wann immeractiveCategoryÄnderungen,filteredArticleses wird automatisch neu berechnet, und die Seite wird automatisch aktualisiert.

Hinweis: computed gibt ein ref zurück, daher erfordert der Zugriff darauf in JS ebenfalls.value.value. Im obigen Beispiel haben wir es jedoch direkt im Template verwendet, wo es automatisch entpackt wird.


Praxis: Kategorienfilterung zum Blog hinzufügen

Wende computed auf die Blog-Startseite an, um Artikel durch Klicken auf Kategorie-Schaltflächen zu filtern.

Beispiel

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

const articles = ref([
{ id: 1, title: 'Vue3 Einstieg kompletter Leitfaden', summary: 'Vue3 von Grund auf lernen', category: 'Vue', date: '2024-05-10' },
{ id: 2, title: 'JS asynchrone Programmierung im Detail', summary: Promise und async/await verstehen, category: 'JavaScript', date: '2024-05-08' },
{ id: 3, title: Praktisches CSS-Grid-Layout, summary: 'Responsives Layout mit Grid implementieren', category: 'CSS', date: '2024-05-05' },
{ id: 4, title: 'Vue3-Reaktivitätsprinzipien', summary: 'Tiefes Verständnis von ref und reactive', category: 'Vue', date: '2024-05-03' },
{ id: 5, title: 'Flexbox kompletter Leitfaden', summary: 'Flex-Layout in einem Artikel lernen', category: 'CSS', date: '2024-05-01' },
])

// Alle Kategorien (dedupliziert)
const categories = computed(() => {
  const cats = articles.value.map(a => a.category)
return ['All', ...new Set(cats)] // 'All' voranstellen
})

// Aktuell ausgewählte Kategorie
const activeCategory = ref('All')

// Artikel nach Kategorie filtern
const filteredArticles = computed(() => {
if (activeCategory.value === 'All') {
    return articles.value
  }
  return articles.value.filter(a => a.category === activeCategory.value)
})
</script>

<template>
  <div class="home">
    <h2>Neueste Artikel</h2>

    <!-- Kategoriefilter-Schaltflächen -->
    <div class="category-bar">
      <button
       v-for="cat in categories"
       :key="cat"
       :class="{ active: activeCategory === cat }"
       @click="activeCategory = cat"
     >
        {{ cat }}
      </button>
    </div>

    <!-- Anzahl der gefilterten Ergebnisse -->
    <p class="result-info">Insgesamt {{ filteredArticles.length }} Artikel</p>

    <!-- Artikelliste -->
    <div class="article-grid">
      <div v-for="article in filteredArticles" :key="article.id" class="card">
        <span class="tag">{{ article.category }}</span>
        <h3>{{ article.title }}</h3>
        <p>{{ article.summary }}</p>
        <span class="date">{{ article.date }}</span>
      </div>
    </div>
  </div>
</template>

<style scoped>
.category-bar {
  display: flex;
  gap: 10px;
  margin-bottom: 20px;
  flex-wrap: wrap;
}

.category-bar button {
  padding: 6px 16px;
  border: 1px solid #ddd;
  border-radius: 20px;
  background: #fff;
  cursor: pointer;
  font-size: 14px;
  transition: all 0.2s;
}

.category-bar button.active {
  background: #427DB8;
  color: #fff;
  border-color: #427DB8;
}

.category-bar button:hover {
  border-color: #427DB8;
}

.result-info {
  color: #999;
  font-size: 14px;
  margin-bottom: 16px;
}
</style>

Wenn Sie nun auf verschiedene Kategorie-Schaltflächen klicken, wird die Artikelliste in Echtzeit gefiltert. Sie müssen keinen DOM-Manipulationscode schreiben; Sie müssen sich nur auf die Logik der Datenänderungen konzentrieren.


Kapitelzusammenfassung

In diesem Kapitel haben Sie die drei Kern-APIs des Vue3-Reaktivitätssystems gemeistert: ref umschließt primitive Typen (unter Verwendung von .value in JS), reactive umschließt Objekte und computed leitet berechnete Daten ab.

Durch computed + Kategoriefilter-Schaltflächen haben Sie das Entwicklungsmuster der 'datengetriebenen Ansichten' kennengelernt — ändern Sie die Daten, die Seite aktualisiert sich automatisch.

Andere Erweiterungen