Vue 3 Tutorial – Vue-Anwendung mit create-vue erstellen
geprüft am 7 September 2026 · 5 Min.
Lege das Projekt mit npm create vue@latest an, antworte bei TypeScript mit „nein“, dann npm install und npm run dev. Eine Vue-Anwendung entsteht aus createApp(App).mount('#app'), ein mit ref() deklarierter Wert erscheint im Template zwischen doppelten geschweiften Klammern und aktualisiert sich von selbst.
Eine Vue-Anwendung ist eine Instanz, die createApp erzeugt und an ein Element der Seite hängt. Dieses Kapitel richtet das Projekt ein und bringt dann einen ersten Wert auf den Bildschirm.
Das Projekt anlegen
Vue bringt einen offiziellen Generator mit, create-vue, der ein für Vue vorkonfiguriertes Vite-Projekt aufsetzt. Öffne ein Terminal in dem Verzeichnis, in dem deine Projekte liegen:
npm create vue@latestDer Generator stellt eine Reihe von Fragen. Für dieses Tutorial antwortest du:
- Project name:
boutique-vue - TypeScript: Nein, wir bleiben bei JavaScript, um nicht zwei Themen auf einmal zu lernen.
- JSX, Vue Router, Pinia, ESLint, Prettier: Nein. Wir ergänzen sie, sobald sie gebraucht werden.
- Vitest: Ja, wenn du Tests schreiben willst, sonst Nein.
Viele Tutorials nennen npm create vue@latest -- --default, um „schneller fertig zu werden“. In create-vue 3.23 schaltet dieses Flag TypeScript ein: Du bekommst eine src/main.ts und tsconfig-Dateien, hier genau das Falsche. Beantworte lieber die Fragen.
Installiere die Abhängigkeiten und starte dann den Dev-Server:
Unter Node 22 bricht das mitgelieferte npm (10.9) mit npm error Cannot read properties of null (reading 'edgesOut') ab, bei einem neuen Projekt wie beim Code dieses Tutorials. Aktualisieren Sie npm vor der Installation: npm install -g npm@latest. Node 24 hat dieses Problem nicht.
cd boutique-vue
npm install
npm run devVite gibt eine Adresse aus, meist http://localhost:5173/. Öffne sie: Die Startseite des Projekts erscheint.
Was der Generator angelegt hat
boutique-vue/
├── index.html ← la seule vraie page HTML du site
├── package.json
├── vite.config.js
├── public/ ← fichiers servis tels quels
└── src/
├── main.js ← point d’entrée : crée et monte l’application
├── App.vue ← composant racine
├── assets/
└── components/Drei Dateien zählen vorerst. Der Generator legt außerdem src/assets/main.css und base.css an, den Stil seiner Startseite: Sie können sie löschen, zusammen mit der Zeile import './assets/main.css' am Anfang von src/main.js, sobald das CSS des Tutorials sie am Kapitelende ersetzt.
index.html enthält einen leeren Container und lädt den Einstiegspunkt. Mehr nicht: Den Rest der Seite erzeugt Vue.
<body>
<div id="app"></div>
<script type="module" src="/src/main.js"></script>
</body>src/main.js erzeugt die Anwendung aus der Wurzelkomponente und mountet sie in diesen Container.
import './assets/main.css'
import { createApp } from 'vue'
import App from './App.vue'
createApp(App).mount('#app')createApp(App) baut die Instanz, .mount('#app') übergibt ihr das DOM-Element, das sie verwalten darf. Ab da gehört alles innerhalb von <div id="app"> zu Vue.
Die erste Komponente
Eine .vue-Datei ist eine Single-File-Komponente: Skript, Template und Style desselben Interface-Bausteins liegen am selben Ort. Leere src/App.vue und schreibe:
<script setup>
import { ref } from 'vue'
const product = ref('T-Shirt')
</script>
<template>
<div class="product-display">
<h1>{{ product }}</h1>
</div>
</template>Speichern: Der Browser zeigt „T-Shirt“ an, ohne neu zu laden. Das ist das Hot Module Replacement von Vite.
Diese Datei wächst bis zum Kapitel über Komponenten, in dem wir sie zerlegen.
Diese sieben Zeilen verstehen
<script setup> sagt Vue, dass dieser Block die Logik der Komponente beschreibt. Alles, was du darin auf oberster Ebene deklarierst, steht im Template zur Verfügung, ganz ohne Export.
ref('T-Shirt') erzeugt eine reaktive Referenz: eine Box, die einen Wert enthält und Vue Bescheid gibt, sobald er sich ändert. Im Skript öffnest du die Box mit .value:
const product = ref('T-Shirt')
console.log(product.value) // 'T-Shirt'
product.value = 'Pull' // die Überschrift ändert sich sofort auf dem BildschirmIm Template dagegen schreibst du {{ product }} ohne .value: Vue packt die Referenz automatisch aus.
Die doppelten geschweiften Klammern sind eine Interpolation. Sie nehmen jeden JavaScript-Ausdruck an, nicht nur einen Variablennamen:
<h1>{{ product }}</h1>
<h1>{{ product.toUpperCase() }}</h1>
<h1>{{ 'Notre ' + product }}</h1>Reaktivität, ganz konkret
Ändere den Startwert in 'Pull' und speichere: Die Überschrift zieht nach. Du hast keine einzige Zeile geschrieben, um das h1 zu suchen und seinen Inhalt zu ändern. Das ist der Kern von Vue: Du beschreibst, was die Seite abhängig vom Zustand anzeigen soll, um die Aktualisierung kümmert sich Vue.
Dieselbe Komponente hieße export default { data() { return { product: 'T-Shirt' } } }, und das Skript käme über this.product daran. Mit <script setup> gibt es kein this: Es gibt nur Variablen.
Und die anderen Build-Tools?
create-vue installiert Vite, das vom Vue-Team empfohlene Werkzeug. Andere Bundler kompilieren .vue-Dateien ebenfalls: Parcel über @parcel/transformer-vue oder webpack mit vue-loader.
Sie funktionieren, sind aber langsamer und abseits des ausgetretenen Pfads. Gemessen am 2. September 2026 an derselben Anwendung aus einer einzigen Komponente:
Vite 8.2.2 build en 1,05 s → 60,57 kB (23,91 kB gzip)
Parcel 2.16.4 build en 10,57 s → 92,77 kBDas Ergebnis von npm run build ist ein Verzeichnis mit statischen Dateien. Was darin steht, entscheidet über dein Ranking, ein Thema für sich.
Für ein neues Projekt bleibt es bei Vite. Die Alternativen lohnen sich nur, wenn deine bestehende Build-Kette ohnehin schon davon abhängt.
Das CSS für dieses Tutorial
Damit die Anwendung nach etwas aussieht, lege src/assets/boutique.css mit den paar Regeln an, die in allen Kapiteln zum Einsatz kommen:
.product-display { display: flex; gap: 32px; padding: 24px; font-family: system-ui, sans-serif; }
.product-image img { width: 240px; }
.variants-wrapper { display: flex; gap: 10px; }
.color-circle { width: 50px; height: 50px; margin-top: 8px; border: 2px solid #d8d8d8; border-radius: 50%; cursor: pointer; }
.button { border: none; background: #1d4ed8; color: #fff; padding: 10px 18px; border-radius: 6px; cursor: pointer; }
.disabledButton { background-color: #d8d8d8; cursor: not-allowed; }Und importiere sie im Einstiegspunkt:
import './assets/boutique.css'
import { createApp } from 'vue'
import App from './App.vue'
createApp(App).mount('#app')brand mit dem Inhalt „Gekkode“ und zeige ihn in der Überschrift vor dem Produktnamen an. Ändere seinen Wert dann im Code und prüfe, ob sich die Seite ohne Neuladen aktualisiert.Häufige Fehler
--default TypeScript ein: Du bekommst eine src/main.ts und tsconfig-Dateien. Führe den Befehl ohne Flag aus und beantworte die TypeScript-Frage mit „nein“.n.value im Skript vergessen | ref() liefert ein Objekt zurück. Im Skript schreibst du product.value, im Template genügt {{ product }}, Vue packt die Referenz aus.node -v, bevor du das Projekt anlegst.