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
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
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
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änkung | Beschreibung | Lösung |
|---|---|---|
| Kann nur Objekttypen umschließen | Primitive Typen wie Zeichenketten, Zahlen können nicht übergeben werden | Verwende ref für primitive Typen |
| Kann nicht als Ganzes ersetzt werden | Das gesamte Objekt kann nicht einem neuen Objekt zugewiesen werden | Verwende Object.assign() oder wechsle zu ref |
Beispiel
// 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
| Szenario | Empfehlung | Beispiel |
|---|---|---|
| Einzelner String/Number/Boolean | ref | const name = ref('小明') |
| Einzelnes Array | ref | const list = ref([]) |
| Einzelnes Objekt | Sowohl ref als auch reactive funktionieren | const user = ref({}) |
| Mehrere nicht zusammenhängende Zustände | Verwende ref für jeden | Ein ref pro Zeile |
| Eine Gruppe stark zusammenhängender Zustände | reactive | z. 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
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
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