Template-Syntax-Rendering
In diesem Kapitel lernst du, die Template-Syntax von Vue zu verwenden, um JS-Daten in HTML zu rendern, sodass die Blog-Startseite eine Liste von Artikelkarten anzeigt.
Interpolationsausdruck {{ }}
Der Interpolationsausdruck ist die grundlegendste Datenbindungsmethode in Vue.
Er "fügt" den Wert einer JS-Variable in das HTML ein. Die Syntax sind doppelte geschweifte Klammern, die den Variablennamen umschließen.
Beispiel
const blogTitle = 'EXAMPLE Frontend Notes'
const author = 'Xiao Ming'
</script>
<template>
<h1>{{ blogTitle }}</h1>
<p>Autor: {{ author }}</p>
<p>Aktuelle Zeit: {{ new Date().toLocaleDateString() }}</p>
</template>
Die Seite wird Folgendes rendern:
EXAMPLE 前端笔记 作者:小明 当前时间:2024/5/15
In die geschweiften Klammern kannst du jeden JS-Ausdruck schreiben: Variablen, Operationen, ternäre Ausdrücke, Funktionsaufrufe - alles ist möglich, aber du kannst keine Anweisungen einfügen (wie z. B.if、for)。
Der Interpolationsausdruck ersetzt nur den Text innerhalb des Tags, nicht das Tag selbst. Zum Beispiel,
in{{ content }}das Tag selbst ist nicht betroffen.
Attributbindung v-bind (Kurzschreibweise :)
Interpolationsausdrücke können nur für Tag-Inhalte verwendet werden, nicht für HTML-Attribute.
Um JS-Variablen in Attributen zu verwenden, musst du diev-bindDirektive verwenden.
Beispiel
const coverUrl = '/images/vue-cover.png'
const linkUrl = '/post/1'
const isActive = true
</script>
<template>
<!-- Vollständige Syntax: v-bind:attribute="variable" -->
<img v-bind:src="coverUrl" v-bind:alt="Artikelcover">
<!-- Kurzschreibweise: direkt :attribute="variable" verwenden -->
<a :href="linkUrl">Ganzen Artikel lesen</a>
<!-- Dynamische Klasse: Objektsyntax verwenden -->
<div :class="{ active: isActive, 'text-bold': true }">
Dieser Text hat sowohl die Klasse active als auch die Klasse text-bold.
</div>
</template>
Die Doppelpunkt-Kurzschreibweiseist die gebräuchlichste Syntax; in der Praxis verwendet man fast niev-bind:den vollständigen Namen.
Listen-Rendering v-for
Die Blog-Startseite muss mehrere Artikel anzeigen. Ein einzelner Artikel ist ein Objekt, und mehrere Artikel bilden ein Objekt-Array.
v-forDu kannst über das Array iterieren und für jedes Element entsprechendes HTML generieren.
Beispiel
// Verwende ein JS-Objekt-Array, um Artikeldaten zu simulieren (wird später geändert, um aus einer JSON-Datei zu laden)
const articles = [
{
id: 1,
title: 'Vollständiger Leitfaden für den Einstieg in Vue3',
summary: 'Lerne die Vue3 Composition API von Grund auf und behandle Kernkonzepte wie ref, reactive, computed.',
date: '2024-05-10',
category: 'Vue',
cover: '/images/vue.png'
},
{
id: 2,
title: 'Asynchrone Programmierung in JavaScript erklärt',
summary: 'Verstehe Promise, async/await, Event-Loop und Microtask-Queue in einem Artikel.',
date: '2024-05-08',
category: 'JavaScript',
cover: '/images/js.png'
},
{
id: 3,
title: 'CSS Grid Layout in der Praxis',
summary: 'Komplexe responsive Layouts lassen sich mit CSS Grid einfach umsetzen, ohne die Einschränkungen von float und flexbox.',
date: '2024-05-05',
category: 'CSS',
cover: '/images/css.png'
}
]
</script>
<template>
<div class="article-list">
<!-- v-for="item in array" :key="eindeutige Kennung" -->
<div v-for="article in articles" :key="article.id" class="card">
<img :src="article.cover" :alt="article.title">
<div class="card-body">
<span class="category">{{ article.category }}</span>
<h3>{{ article.title }}</h3>
<p>{{ article.summary }}</p>
<span class="date">{{ article.date }}</span>
</div>
</div>
</div>
</template>
<style scoped>
.article-list {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
gap: 24px;
margin-top: 20px;
}
.card {
background: #fff;
border-radius: 12px;
overflow: hidden;
box-shadow: 0 2px 12px rgba(0,0,0,0.08);
transition: transform 0.2s;
}
.card:hover {
transform: translateY(-4px);
}
.card img {
width: 100%;
height: 180px;
object-fit: cover;
}
.card-body {
padding: 16px;
}
.category {
display: inline-block;
padding: 2px 10px;
background: #E8EEF5;
color: #427DB8;
border-radius: 12px;
font-size: 12px;
}
.card-body h3 {
margin: 10px 0 8px;
font-size: 18px;
}
.card-body p {
color: #666;
font-size: 14px;
line-height: 1.6;
}
.date {
display: block;
margin-top: 10px;
font-size: 12px;
color: #999;
}
</style>
Die Bedeutung des key-Attributs
:keyEr ist ein unverzichtbarer Begleiter von v-for und teilt Vue die Identität jedes Elements mit.
Wenn sich die Reihenfolge des Arrays ändert (z. B. Einfügen, Löschen, Sortieren), verwendet Vue den key, um zu bestimmen, welche DOM-Knoten aktualisiert werden müssen und welche wiederverwendet werden können.
| Wert von key | Konsequenz |
|---|---|
| Eindeutige ID (empfohlen) | Verfolgt jedes Element korrekt und aktualisiert effizient |
| Array-Index | Kann bei Einfügen/Löschen zu Zustandsverwirrung führen (z. B. werden Inhalte von Eingabefeldern vertauscht) |
| Kein Key | Die Konsole gibt eine Warnung aus; Vue verwendet standardmäßig die Strategie der "In-Place-Aktualisierung", die eine schlechte Leistung hat. |
Gib v-for immer einen eindeutigen und stabilen key; verwende nicht index als key. Das ist eine der wichtigsten Gewohnheiten in der Vue-Entwicklung.
Bedingtes Rendern v-if / v-else
Wenn du unterschiedliche Inhalte unter unterschiedlichen Bedingungen anzeigen musst, verwende diev-if-Familie von Direktiven.
Beispiel
import { ref } from 'vue'
const articles = ref([]) // Artikelliste (leeres Array bedeutet vorerst keine Daten)
const isLoading = ref(true) // Ladezustand
// Datenladen simulieren: Daten nach 2 Sekunden eintragen
setTimeout(() => {
articles.value = [
{ id: 1, title: 'Erste Schritte mit Vue3', summary: '...' },
{ id: 2, title: 'React-Vergleich', summary: '...' }
]
isLoading.value = false
}, 2000)
</script>
<template>
<div>
<!-- Wird geladen -->
<p v-if="isLoading">Wird geladen, bitte warten...</p>
<!-- Liste anzeigen, wenn Daten vorhanden sind -->
<div v-else-if="articles.length > 0">
<div v-for="article in articles" :key="article.id" class="card">
<h3>{{ article.title }}</h3>
<p>{{ article.summary }}</p>
</div>
</div>
<!-- Leerzustand anzeigen, wenn keine Daten vorhanden sind -->
<p v-else>Noch keine Artikel, bitte bleiben Sie dran.</p>
</div>
</template>
Dieses Muster deckt die drei häufigsten UI-Zustände ab:Laden → Daten vorhanden → Keine Daten。
v-if vs. v-show
| Direktive | Umschaltmethode | Anfängliche Renderkosten | Umschaltkosten | Anwendungsfälle |
|---|---|---|---|---|
| v-if | Fügt DOM-Knoten hinzu/entfernt sie | Gering (rendert nicht) | Hoch (baut DOM neu auf) | Szenarien, in denen sich die Bedingung selten ändert, wie z. B. Berechtigungssteuerung |
| v-show | Schaltet die CSS-Eigenschaft display um | Hoch (rendert immer) | Gering (ändert nur Stile) | Szenarien mit häufiger Umschaltung, wie z. B. beim Tab-Wechsel |
Leicht zu merken: v-show für häufiges Umschalten verwenden, v-if für stabile Bedingungen.
Hands-on: Vollständige Blog-Startseite
Kombiniere die zuvor gelernte Template-Syntax und schreibe eine vollständige Blog-Startseiten-Komponente.
Beispiel
import { ref } from 'vue'
// Artikel-Daten (derzeit hartkodiert; in späteren Kapiteln werden sie so geändert, dass sie per fetch geladen werden)
const articles = ref([
{
id: 1,
title: 'Vollständiger Leitfaden für den Einstieg in Vue3',
summary: 'Lerne die Vue3 Composition API von Grund auf und behandle Kernkonzepte wie ref, reactive, computed.',
date: '2024-05-10',
category: 'Vue',
cover: '/images/vue.png'
},
{
id: 2,
title: 'Asynchrone Programmierung in JavaScript erklärt',
summary: 'Verstehe Promise, async/await, Event-Loop und Microtask-Queue in einem Artikel.',
date: '2024-05-08',
category: 'JavaScript',
cover: '/images/js.png'
},
{
id: 3,
title: 'CSS Grid Layout in der Praxis',
summary: 'Komplexe responsive Layouts einfach mit CSS Grid umsetzen.',
date: '2024-05-05',
category: 'CSS',
cover: '/images/css.png'
}
])
</script>
<template>
<div class="home">
<h2 class="section-title">Neueste Artikel</h2>
<!-- Wird geladen -->
<p v-if="!articles.length" class="empty-tip">Noch keine Artikel vorhanden, bitte schauen Sie bald wieder vorbei.</p>
<!-- Liste der Artikelkarten -->
<div v-else class="article-grid">
<div
v-for="article in articles"
:key="article.id"
class="article-card"
>
<img :src="article.cover" :alt="article.title" class="card-cover">
<div class="card-content">
<span class="card-category">{{ article.category }}</span>
<h3 class="card-title">{{ article.title }}</h3>
<p class="card-summary">{{ article.summary }}</p>
<span class="card-date">{{ article.date }}</span>
</div>
</div>
</div>
</div>
</template>
<style scoped>
.home {
max-width: 960px;
margin: 0 auto;
padding: 20px;
}
.section-title {
font-size: 24px;
margin-bottom: 20px;
color: #333;
}
.article-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
gap: 24px;
}
.article-card {
background: #fff;
border-radius: 12px;
overflow: hidden;
box-shadow: 0 2px 12px rgba(0,0,0,0.08);
transition: transform 0.2s, box-shadow 0.2s;
cursor: pointer;
}
.article-card:hover {
transform: translateY(-4px);
box-shadow: 0 8px 24px rgba(0,0,0,0.12);
}
.card-cover {
width: 100%;
height: 180px;
object-fit: cover;
}
.card-content {
padding: 16px;
}
.card-category {
display: inline-block;
padding: 2px 10px;
background: #E8EEF5;
color: #427DB8;
border-radius: 12px;
font-size: 12px;
margin-bottom: 8px;
}
.card-title {
font-size: 18px;
margin-bottom: 8px;
color: #222;
}
.card-summary {
font-size: 14px;
color: #666;
line-height: 1.6;
margin-bottom: 12px;
}
.card-date {
font-size: 12px;
color: #999;
}
.empty-tip {
text-align: center;
color: #999;
padding: 60px 0;
font-size: 16px;
}
</style>
Kapitelzusammenfassung
In diesem Kapitel haben Sie vier zentrale Funktionen der Template-Syntax kennengelernt:{{ }}Interpolation zur Anzeige von Daten,v-bind(Kurzschreibweise:) zum Binden von Attributen,v-forSchleifen zum Rendern von Listen,v-if/v-elseBedingungen zur Steuerung der Sichtbarkeit.
Zu diesem Zeitpunkt kann die Blog-Startseite bereits Artikelkarten dynamisch auf Basis von JS-Daten rendern.
Andere Erweiterungen