Skip to content

Alles für WordPress, Webentwicklung — und mehr

⚡ Die Grundlagen von Vue 3 lernen: von einem leeren Ordner zu Komponenten

⚡ Die Grundlagen von Vue 3 lernen: von einem leeren Ordner zu Komponenten

Sie betrachten Vue 3 und sehen ein elegantes Frontend-Framework aus dem Kreis der großen Drei. React, Angular, Vue: das klingt nach ernsthafter Technik. Dann öffnen Sie das erste Tutorial, und dort erwarten Sie vite, create-vue und .vue-Dateien mit Transpilern… Dabei können Sie Vue tatsächlich mit einer einzigen <script>-Zeile einbinden und sofort mit dem Coden beginnen. Keine Bundler, kein JSX, keine Konfigurationshölle.

Der Abstand zwischen „Ich möchte es ausprobieren" und „Ich habe eine Komponente geschrieben" ist hier kürzer als irgendwo sonst. Doch die meisten Tutorials schließen diese Lücke nicht; sie geben die Dokumentation bruchstückhaft wieder, ohne Ihnen das Gesamtbild zu vermitteln. Sie sehen verstreute Syntax-Schnipsel und erkennen nicht, wie daraus eine Anwendung wird.

Dieser Leitfaden beschreibt exakt den Weg, den wir selbst mit Vue gegangen sind: von einem leeren Ordner bis zu Komponenten mit Props. Sie schreiben und führen jede Zeile selbst aus. Keine Zauberei, nur funktionierender Code und ein Verständnis von Reaktivität, der zentralen Superkraft von Vue.

💡 Kurzer Überblick:

  • Bauen Sie eine Vue-App von einem CDN auf und binden Sie sie ins DOM ein: Ihre erste lauffähige Instanz in 5 Minuten
  • Gehen Sie vier zentrale Direktiven durch, v-for, v-if, v-on und v-bind: die Säulen jedes Vue-Templates
  • Zerlegen Sie computed und methods: wann cachen und wann aufrufen
  • Extrahieren Sie Logik in Komponenten und übergeben Sie Daten per Props: ein Schritt in Richtung echter Architektur

Eine Vue-App erstellen

Fangen wir bei null an. Kein create-vue, vite oder vue-cli, nur ein Ordner mit zwei Dateien.

Erstellen Sie das Verzeichnis und die Dateien im Terminal:

1mkdir vue3-intro
2cd vue3-intro
3touch index.html app.js

Oder erledigen Sie dasselbe über Ihren Dateimanager. Öffnen Sie nun index.html und schreiben Sie das Grundgerüst:

1<!DOCTYPE html>
2<html lang="ru">
3<head>
4 <meta charset="UTF-8">
5 <meta name="viewport" content="width=device-width, initial-scale=1.0">
6 <script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
7 <title>Vue 3 — first steps</title>
8</head>
9<body>
10 <div id="app"></div>
11 <script src="./app.js"></script>
12</body>
13</html>

Drei entscheidende Zeilen. <script src="https://unpkg.com/vue@3/dist/vue.global.js"> lädt Vue 3 von einem CDN. Das ist der schnellste Einstieg: Die Bibliothek wird wie eine gewöhnliche JavaScript-Datei geladen, ohne Build-Schritt. <div id="app"> legt den Einhängepunkt fest: die Stelle im DOM, an der Vue „leben" wird. Die dritte Zeile importiert app.js, wo wir die Logik definieren.

Nun befüllen wir app.js:

1const app = Vue.createApp({
2 data() {
3 return {
4 course: 'Introduction to Vue 3'
5 }
6 }
7})
8
9app.mount('#app')

Die Methode Vue.createApp() erzeugt eine Applikationsinstanz. Sie erhält ein Optionsobjekt; hier haben wir eine Eigenschaft course über die Funktion data() deklariert. Vue macht jede von data() zurückgegebene Eigenschaft reaktiv: Ändert sich ein Wert, aktualisiert sich das DOM automatisch. Keine manuellen Eingriffe in den DOM-Baum nötig.

Doch die Anwendung muss an ein Element auf der Seite „angehängt" werden. Genau das bewirkt app.mount('#app'). Ohne diese Zeile reagiert Vue auf keine Änderungen: Die Instanz ist erstellt, aber nicht gestartet.

Jetzt fehlt nur noch die Anzeige der Eigenschaft im HTML. Innerhalb von <div id="app"> schreiben Sie:

1<h1>{{ course }}</h1>

Doppelte geschweifte Klammern {{ }} sind die Interpolation, der primäre Weg, um Daten in Vue-Templates auszugeben. Alles innerhalb von {{ }} wird von Vue durch den entsprechenden Eigenschaftswert aus data() ersetzt.

Erste Vue 3 App im Browser

Öffnen Sie index.html in Ihrem Browser. Die Seite zeigt den Text an. Ihre erste App ist fertig, und Sie haben sie selbst geschrieben, statt sie über eine CLI generieren zu lassen.

Listen rendern

In einer echten Anwendung arbeiten Sie fast immer mit Arrays: Produkte, Tags, Beiträge. Vue stellt dafür die Direktive v-for bereit.

Ergänzen wir ein Tags-Array in data():

1const app = Vue.createApp({
2 data() {
3 return {
4 course: 'Introduction to Vue 3',
5 description: 'Basic guide to Vue 3 for beginners',
6 price: '$19.99',
7 tags: ['Vue', 'Frontend', 'JavaScript']
8 }
9 }
10})

Und im HTML eine Liste:

1<ul>
2 <li v-for="tag in tags">{{ tag }}</li>
3</ul>

Die Direktive v-for iteriert über das tags-Array und erzeugt für jedes Element ein eigenes <li>. Die Variable tag innerhalb der Schleife ist das aktuelle Element. Das Ergebnis sieht so aus:

Vue 3 Tag-Liste mit der v-for Direktive

Eine wichtige Nuance: Beim Iterieren über ein Array benötigt jedes DOM-Element einen eindeutigen Schlüssel. Vue nutzt ihn, um die Identität der Knoten bei Aktualisierungen nachzuverfolgen, was das erneute Rendern beschleunigt und zustandsbezogene Fehler verhindert.

1<ul>
2 <li v-for="(tag, index) in tags" :key="index">{{ tag }}</li>
3</ul>

:key ist die Kurzform von v-bind:key, die das key-Attribut an den Indexwert bindet. Wenn Sie ein Array mit Objekten haben, zum Beispiel { id: 1, name: 'Vue' }, verwenden Sie id als Schlüssel anstelle des Index. Der Index ändert sich beim Umsortieren, während id stabil bleibt, was zuverlässiger ist.

Bedingtes Rendering

Häufig müssen Sie ein Element abhängig von einer Bedingung ein- oder ausblenden: etwa einen Kaufen-Button nur, wenn der Kurs verfügbar ist. Vue realisiert dies mit der v-if-Direktive.

Fügen wir ein available-Flag zu data() hinzu:

1data() {
2 return {
3 course: 'Introduction to Vue 3',
4 description: 'Basic guide to Vue 3 for beginners',
5 price: '$19.99',
6 available: true,
7 tags: [
8 { id: 1, name: 'Vue' },
9 { id: 2, name: 'Frontend' },
10 { id: 3, name: 'JavaScript' }
11 ]
12 }
13}

Und verwenden es im Markup:

1<p v-if="available">Course available for purchase!</p>
2<p v-else>Unfortunately, the course is currently unavailable.</p>

v-if wertet den Ausdruck in den Anführungszeichen aus. Ist er truthy, wird der erste Block gerendert, andernfalls greift v-else. Führen Sie app.available = false in der Browser-Konsole aus und beobachten Sie, wie die Seite sofort reagiert.

Konditionales Rendering in Vue 3 mit v-if

Neben v-if / v-else gibt es auch v-else-if für Bedingungsketten sowie v-show. Der Unterschied ist grundlegend: v-if entfernt das Element vollständig aus dem DOM, während v-show lediglich display: none umschaltet. Wählen Sie v-if, wenn sich die Bedingung selten ändert. Nutzen Sie v-show für häufiges Umschalten wie bei Tabs, wo Performance eine Rolle spielt.

Events behandeln

Die v-on-Direktive, kurz @, horcht auf DOM-Events: Klicks, Eingaben, Hover. Wenn ein Event ausgelöst wird, führt Vue die angegebene Methode oder den Ausdruck aus.

Fügen wir den App-Optionen eine purchase-Methode hinzu:

1const app = Vue.createApp({
2 data() {
3 return {
4 course: 'Introduction to Vue 3',
5 description: 'Basic guide to Vue 3 for beginners',
6 price: '$19.99',
7 available: true,
8 tags: [
9 { id: 1, name: 'Vue' },
10 { id: 2, name: 'Frontend' },
11 { id: 3, name: 'JavaScript' }
12 ]
13 }
14 },
15 methods: {
16 purchase() {
17 console.log('Course purchased!')
18 }
19 }
20})

Der Abschnitt methods enthält Funktionen, die im Template und in anderen Methoden über this zugänglich sind. Binden wir nun den Aufruf an einen Button:

1<button @click="purchase">Buy</button>
Klickbehandlung in Vue 3 mit v-on

Für einfache Aktionen können Sie den Code direkt in @click schreiben:

1<button @click="available = !available">Toggle availability</button>
Button-Zustand in Vue 3 umschalten

Inline-Code wie dieser ist praktisch für kurze Operationen, etwa das Umschalten eines Flags. Verlagern Sie komplexe Logik jedoch stets in Methoden; das Template sollte lesbar bleiben. Eine einfache Regel: counter += 1 ist im Template in Ordnung, aber zehn Zeilen Einkaufslogik gehören in eine Methode.

Attribute binden

Attribute wie src, href oder alt müssen häufig dynamisch sein. Die Direktive v-bind, kurz :, bindet einen Attributwert an einen Vue-Ausdruck.

Ergänzen wir Daten für ein Bild:

1data() {
2 return {
3 // ...other properties
4 imgURL: 'https://catalins.tech/img',
5 imgDescription: 'Photo of a desk with a computer'
6 }
7}

Im Template binden Sie diese an ein <img>:

1<img :src="imgURL" :alt="imgDescription" width="500" height="350">

Die ausführliche Form wäre v-bind:src="imgURL"; der Doppelpunkt ist lediglich syntaktischer Zucker. Vue verfolgt nun imgURL und imgDescription: Ändern Sie die Werte in data(), und das Bild auf der Seite aktualisiert sich automatisch. Das ist Reaktivität in Aktion.

Bildattribute mit v-bind binden

Dasselbe Prinzip gilt für Attribute wie :href, :disabled und :class sowie für alle weiteren. Probieren Sie es selbst aus: Fügen Sie einen Link mit einem dynamischen href aus data() hinzu und stellen Sie sicher, dass er ohne eine einzige zusätzliche Zeile funktioniert.

Computed Properties

Manchmal müssen Daten vor der Anzeige transformiert werden: einen Preis formatieren, Vor- und Nachnamen verketten, eine Bedingung prüfen. Vue stellt hierfür computed-Properties bereit.

Angenommen, Sie möchten stets eine Bildbeschreibung haben, auch wenn das Feld imgDescription leer ist. Schreiben wir eine Computed Property:

1const app = Vue.createApp({
2 data() {
3 return {
4 course: 'Introduction to Vue 3',
5 description: 'Basic guide to Vue 3 for beginners',
6 price: '$19.99',
7 available: true,
8 imgURL: 'https://catalins.tech/img',
9 imgDescription: 'Photo of a desk with a computer',
10 tags: [
11 { id: 1, name: 'Vue' },
12 { id: 2, name: 'Frontend' },
13 { id: 3, name: 'JavaScript' }
14 ]
15 }
16 },
17 computed: {
18 hasImageDescription() {
19 return this.imgDescription.length > 0
20 ? this.imgDescription
21 : 'Automatic image description'
22 }
23 }
24})

Verwenden Sie nun die Computed Property im Template anstelle der Rohdaten:

1<img :src="imgURL" :alt="hasImageDescription" width="500" height="350">

Vue speichert das Ergebnis einer computed-Property zwischen und berechnet es nur neu, wenn sich ihre Abhängigkeiten ändern, in unserem Fall imgDescription. Das ist effizienter, als bei jedem Rendern eine Funktion aufzurufen.

Eine wichtige Regel: Computed Properties sind zum Anzeigen von Daten gedacht, nicht zu deren Veränderung. Ändern Sie keinen Anwendungszustand innerhalb von computed; nutzen Sie dafür Methoden.

Methoden vs. Computed Properties

Der Unterschied zwischen methods und computed läuft auf eine Frage hinaus: Ändern Sie Daten oder zeigen Sie einen abgeleiteten Wert an?

Computed Properties gehören zur Darstellungsschicht. Formatierung, Filterung, Bedingungsprüfungen, String-Verkettung. Sie werden zwischengespeichert und haben keine Seiteneffekte.

Methoden sind für Aktionen da. Einen Wert in data() ändern, eine Anfrage senden, ein Flag umschalten. Sie werden explizit aufgerufen und können alles tun.

Ein typisches Anti-Pattern ist das Modifizieren von this.course innerhalb einer computed-Property. Eine Computed Property reagiert auf Änderungen in course, sollte diese aber nicht selbst verändern. Verwenden Sie für das Ändern von Daten stets eine Methode. Lassen Sie das Template beschreiben, „was angezeigt werden soll", nicht „wie es berechnet wird".

Komponenten und Props

Wenn eine Anwendung wächst, wird es unüberschaubar, alles in einer einzigen Datei zu halten. Vue erlaubt es Ihnen, die Oberfläche in Komponenten zu zerlegen: isolierte Blöcke mit eigener Logik, eigenem Template und eigenen Styles.

Erstellen wir unsere erste Komponente, CourseCard:

1mkdir components
2touch components/CourseCard.js

In components/CourseCard.js definieren Sie die Komponente:

1app.component('coursedisplay', {
2 data() {
3 return {
4 course: 'Introduction to Vue 3',
5 description: 'Basic guide to Vue 3 for beginners',
6 price: '$19.99',
7 available: true,
8 imgURL: 'https://catalins.tech/img',
9 imgDescription: 'Photo of a desk with a computer',
10 tags: [
11 { id: 1, name: 'Vue' },
12 { id: 2, name: 'Frontend' },
13 { id: 3, name: 'JavaScript' }
14 ]
15 }
16 },
17 computed: {
18 hasImageDescription() {
19 return this.imgDescription.length > 0
20 ? this.imgDescription
21 : 'Automatic image description'
22 }
23 },
24 template: `
25 <img :src="imgURL" :alt="hasImageDescription" width="500" height="350">
26 <h1>{{ course }}</h1>
27 <p>{{ description }}</p>
28 <p>{{ price }}</p>
29 <button @click="available = !available">Buy</button>
30 <ul>
31 <li v-for="tag in tags" :key="tag.id">{{ tag.name }}</li>
32 </ul>
33 <p v-if="available">Course available for purchase!</p>
34 <p v-else>Unfortunately, the course is currently unavailable.</p>
35 `
36})

Das erste Argument von app.component() ist der Name, den wir im HTML als Tag verwenden: <coursedisplay></coursedisplay>. Das zweite ist ein Objekt mit data(), computed und template, den „Interna" der Komponente.

Nun binden wir die Komponente in index.html ein und verwenden sie:

1<div id="app">
2 <coursedisplay></coursedisplay>
3</div>
4<script src="./app.js"></script>
5<script src="./components/CourseCard.js"></script>
6<script>
7 const mountedApp = app.mount('#app')
8</script>

Wir haben die Komponentendatei importiert, sie als benutzerdefiniertes Tag genutzt und die Anwendung direkt im HTML gemountet. Die Kurslogik ist jetzt in CourseCard gekapselt, während app.js nur noch für das Erzeugen der Instanz zuständig ist.

Props: Daten zwischen Komponenten übergeben

Props (kurz für Properties) sind der Mechanismus, um Daten von einer Elternkomponente an eine Kindkomponente zu übergeben. Die Kindkomponente deklariert, welche Props sie akzeptiert, und die Elternkomponente übergibt sie als Attribute.

Fügen wir CourseCard eine paid-Prop hinzu, die anzeigt, ob der Kurs kostenpflichtig oder kostenlos ist:

1app.component('coursedisplay', {
2 props: {
3 paid: {
4 type: Boolean
5 }
6 },
7 // ...rest of the configuration
8})

Die Elternkomponente, in unserem Fall app.js, übergibt den Wert:

1const app = Vue.createApp({
2 data() {
3 return {
4 allCourses: 1,
5 paid: true
6 }
7 }
8})

Und in index.html reichen wir die Prop durch:

1<coursedisplay :paid="paid"></coursedisplay>

Vue validiert automatisch den Typ des übergebenen Werts. Wird ein Boolean erwartet, aber ein String empfangen, gibt das Framework eine Warnung in der Konsole aus. Das bewahrt Sie vor dummen Fehlern, wenn die Codebasis wächst.

Um eine Prop verpflichtend zu machen, ergänzen Sie ihre Definition um required: true. Vue beschwert sich dann, wenn die Elternkomponente keinen Wert übergibt, sodass Sie von dem Problem erfahren, bevor es die Oberfläche zerstört.

Den vollständigen Code zu dieser Anleitung finden Sie im vue3-intro-Repository auf GitHub, das die fertigen Dateien index.html, app.js und components/CourseCard.js enthält. Forken Sie es und experimentieren Sie.

Zugehöriges Video

Um den Stoff durch Praxis zu festigen, sehen Sie sich die erste Lektion des Net Ninja Vue-3-Kurses an; sie ergänzt diese Anleitung hervorragend durch einen Live-Code-Walkthrough:

⁉️🤔 Häufig gestellte Fragen

Kann ich Vue 3 ohne Bundler in Produktion einsetzen?

Ja, die Einbindung per CDN (unpkg.com/vue@3/dist/vue.global.js) funktioniert auch in Produktion. Für echte Projekte empfehlen wir jedoch den Umstieg auf Vite: Sie erhalten Tree-Shaking, Code-Splitting und Single-File Components, was die Entwicklung mit wachsender Anwendung drastisch vereinfacht. Die Starter-Vorlage npm create vue@latest richtet all das in einer Minute ein.

Wie unterscheidet sich v-if von v-show?

v-if entfernt das Element vollständig aus dem DOM, wenn die Bedingung falsch ist. v-show belässt das Element im DOM, schaltet aber die CSS-Eigenschaft display: none um. Verwenden Sie v-if, wenn sich die Bedingung selten ändert, zum Beispiel bei der Benutzerrolle. Verwenden Sie v-show für häufiges Umschalten wie bei Tabs, wo Render-Geschwindigkeit zählt und Sie das Neuerstellen von Knoten vermeiden möchten.

Ist:key in v-for erforderlich?

Technisch funktioniert v-for ohne :key, aber Vue gibt eine Warnung in der Konsole aus. Ohne Key kann das Framework nicht nachverfolgen, welches DOM-Element zu welchem Datenelement gehört, was zu Fehlern beim Umsortieren und Löschen führt. Geben Sie immer :key mit einer eindeutigen Kennung an, einer id aus Ihren Daten, nicht dem Array-Index.

Was ist der Unterschied zwischen data() und computed?

data() speichert den ursprünglichen Zustand, die „rohen" Daten. computed leitet daraus einen Wert für die Anzeige ab: einen formatierten String, ein gefiltertes Array, ein Validierungsergebnis. Eine Computed Property aktualisiert sich automatisch, wenn sich ihre Abhängigkeiten ändern, und wird zwischen Renderings gecached. Methoden hingegen werden bei jedem Aufruf neu ausgeführt und sind für Aktionen gedacht, nicht für die Anzeige.

Kann man Options API und Composition API mischen?

Ja, Sie können beide Stile in einem einzigen Projekt verwenden. Vue 3 unterstützt die Options API vollständig, während die Composition API ein zusätzliches Werkzeug für komplexe Szenarien ist. Zum Lernen empfehlen wir, mit der Options API zu beginnen: Sie ist strukturierter und näher am mentalen Modell „eine Komponente ist ein Objekt mit Optionen".

Nächste Schritte: Ihr weiterer Weg mit Vue 3

Sie haben Ihre erste App gebaut, Direktiven, Computed Properties und Komponenten kennengelernt. Das ist das Fundament, auf dem jedes Projekt aufbaut, von einer Landingpage bis zu einem Admin-Panel.

Drei Wege bieten sich an. Erstens: Festigen durch Praxis, greifen Sie sich eine öffentliche API wie JSONPlaceholder und zeigen Sie eine Liste von Beiträgen mit Filterung über computed an. Zweitens: Umstieg auf Vite und .vue-Dateien, die offizielle Vue-3-Dokumentation führt Sie in einer Stunde von create-vue zu Ihrer ersten SFC. Drittens: Lernen Sie Vue Router und Pinia für den Bau einer vollwertigen SPA.

Wenn Sie Vue ganz ohne Installation ausprobieren möchten, lesen Sie den Artikel zur Einbindung von Vue per CDN. Den Starter-Code aus dieser Anleitung finden Sie im vue3-intro-Repository; forken Sie es und experimentieren Sie.