Was ist Vue?
Vue ist ein progressives JavaScript Framework zum Erstellen von Benutzeroberflächen. Die Wortwahl ist bewusst: Sie können Vue einfach in eine einzelne Seite einbinden, um ein einzelnes Widget zu verbessern, oder es zusammen mit einem Build-Tool für die Entwicklung einer vollständigen Anwendung nutzen. Es ist kein Rewrite erforderlich, um einen Mehrwert zu erzielen, und das Framework wächst mit Ihren Anforderungen mit.
Im Kern besteht Vue aus zwei Komponenten: einer Template-Syntax, die HTML erweitert, und einem Reaktivitäts-System, das Ihre Daten verfolgt und die View automatisch aktualisiert. Sie definieren, was die UI anzeigen soll, und Vue hält dies synchron.
Single-File Components
Eine Vue-Komponente befindet sich normalerweise in einer .vue-Datei mit drei Blöcken: einem Template, einem Script und Styles. Da diese zusammengehalten werden, ist eine Komponente eine einzelne, in sich geschlossene Einheit.
<!-- Card.vue -->
<script setup>
defineProps({ title: String });
</script>
<template>
<article class="card">
<h3>{{ title }}</h3>
<slot />
</article>
</template>
<style scoped>
.card {
border-radius: 1rem;
padding: 1.5rem;
}
</style>
<style scoped> begrenzt das CSS automatisch auf diese Komponente, sodass Klassennamen nicht nach außen dringen können. <script setup> ist ein Compiler-Makro, das die Composition API prägnanter macht und der moderne Standard ist.
Template-Syntax
Vue-Templates sind HTML mit einem kleinen Satz an Direktiven. Für die Interpolation werden doppelte geschweifte Klammern verwendet, und Direktiven sind Attribute, die mit v- beginnen.
<!-- profile.vue -->
<template>
<h1>{{ user.name }}</h1>
<p v-if="user.online">Online</p>
<p v-else>Offline</p>
<ul>
<li v-for="post in posts" :key="post.id">
{{ post.title }}
</li>
</ul>
<img :src="user.avatar" :alt="user.name" />
<button @click="follow">Follow</button>
</template>
Die Kurzschreibweisen lassen sich so lesen: :src bindet ein Attribut an einen Ausdruck und @click reagiert auf ein Event. v-if steuert das bedingte Rendering und v-for führt Schleifen mit einem :key für effiziente Updates aus. Das Template wird in Render-Funktionen kompiliert, allerdings müssen Sie diese nur selten einsehen.
Reaktivität: ref und reactive
Das Reaktivitätssystem von Vue überwacht deine Daten und löst ein Re-Render aus, sobald sie sich ändern. In der Composition API erstellst du reaktive Werte mit ref oder reactive.
<script setup>
import { ref, reactive } from "vue";
const count = ref(0); // .value in script
const user = reactive({ // proxy, no .value
name: "Ada",
online: true,
});
function increment() {
count.value += 1;
}
</script>
ref umschließt jeden beliebigen Wert, auf den im Script über .value zugegriffen wird, während Templates ihn automatisch für dich auspacken (unwrap). reactive gibt einen tiefen reaktiven Proxy für ein Objekt zurück. Eine gängige Konvention ist die konsistente Verwendung von ref, da es sowohl für Primitive funktioniert als auch einfach neu zugewiesen werden kann.
Computed und watch
Zwei Funktionen handhaben abgeleitete Werte und Side Effects.
<script setup>
import { ref, computed, watch } from "vue";
const items = ref([10, 20, 30]);
const total = computed(() =>
items.value.reduce((sum, n) => sum + n, 0),
);
watch(items, (next, prev) => {
console.log("items changed", prev, next);
});
</script>
computed cached sein Ergebnis und berechnet dieses nur dann neu, wenn sich eine Abhängigkeit ändert – nutze es immer dann, wenn ein Wert aus einem anderen State abgeleitet wird. watch führt einen Callback aus, wenn sich eine Quelle ändert, und ist für Side Effects wie Logging, Fetching oder Speichern gedacht. Es ist ein häufiger Fehler, watch zu verwenden, um einen Wert zu berechnen.
Props, Emits und Slots
Daten fließen über Props nach unten und über emitted events nach oben.
<!-- Child.vue -->
<script setup>
const props = defineProps({
label: { type: String, required: true },
});
const emit = defineEmits(["select"]);
function handleClick() {
emit("select", props.label);
}
</script>
<template>
<button @click="handleClick">{{ label }}</button>
</template>
<!-- Parent.vue -->
<Child label="Save" @select="onSelect" />
Props sind im Child-Component read-only, wodurch die Source of Truth in der Parent-Component bleibt. Slots ermöglichen es einer Parent-Component, Markup an eine Child-Component zu übergeben – das Äquivalent zu children in React.
Composables
Der größte Vorteil der Composition API ist die wiederverwendbare Logik. Ein Composable ist eine Funktion, die Reaktivität nutzt und einen State zurückgibt; sie wird mit einem use-Präfix benannt.
// useFetch.js
import { ref, watchEffect } from "vue";
export function useFetch(url) {
const data = ref(null);
const error = ref(null);
watchEffect(async () => {
data.value = null;
error.value = null;
try {
const res = await fetch(url.value);
data.value = await res.json();
} catch (err) {
error.value = err;
}
});
return { data, error };
}
Composables teilen die Logik, nicht den State. Daher erhält jede Komponente, die useFetch aufruft, ihre eigenen unabhängigen Daten. Dies ist das Vue-Äquivalent zu einem Custom Hook.
Routing und State
Vue Router übernimmt die Navigation über ein deklaratives Mapping von URL zu Komponente, und Pinia ist der offizielle Store für den shared state.
// router.js
import { createRouter, createWebHistory } from "vue-router";
export const router = createRouter({
history: createWebHistory(),
routes: [
{ path: "/", component: Home },
{ path: "/users/:id", component: UserProfile },
],
});
Nutzen Sie einen Store, wenn mehrere weit voneinander entfernte Komponenten auf denselben State zugreifen müssen. Für lokale Daten oder die Kommunikation zwischen Eltern- und Kindkomponenten reichen Props und Composables in der Regel aus.
Best Practices
- Verwende
script setupund die Composition API für neuen Code. - Bevorzuge
computedgegenüberwatchfür abgeleitete Werte. - Halte Props schreibgeschützt und emitte Events für Änderungen.
- Extrahiere wiederverwendbare Logik in Composables.
- Nutze
scopedStyles oder CSS Modules, um Styles lokal zu halten. - Benenne Composables mit einem
use-Präfix. - Vermeide den direkten Zugriff auf den State von Child-Komponenten; kommuniziere stattdessen über Props und Emits.
Häufige Fehler
- Das Vergessen von
.valuebei einer ref innerhalb von script. - Die Verwendung von
watchzur Berechnung eines Wertes, dencomputedableiten sollte. - Das Mutieren von Props in einer Child-Komponente anstatt eines Events zu emittieren.
- Das Destructuring eines
reactive-Objekts, wodurch die Reaktivität verloren geht. - Das Speichern des gesamten States in einem globalen Store, obwohl ein lokaler State ausreichen würde.
- Das Vermischen von Options API und Composition API ohne ersichtlichen Grund.
Wie geht es weiter?
Vue bietet einen sanften Einstieg in Komponenten-Frameworks und ist gleichzeitig extrem skalierbar. Nutze Nuxt für Server Rendering und Routing-Konventionen, vergleiche den Ansatz mit React und Svelte und halte deine JavaScript-Kenntnisse auf dem neuesten Stand. Baue anschließend ein kleines Projekt – zum Beispiel eine filterbare Liste oder ein Formular mit Validierung – und lass die Reaktivität die Arbeit erledigen.