Vue-Tutorial
Vue-3-Single-File-Komponenten mit typisierten Props, defineModel
Zwei-Wege-Bindung und v-bind="$attrs" -Durchreichung.
Was du baust
Ein kleines Kontaktformular — beschriftetes Eingabefeld, Absenden-Schaltfläche, v-model
-Bindung, echtes Tastatur- und Screenreader-Verhalten — zuerst nackt, dann gestaltet, in etwa 10 Minuten.
Bevor du anfängst
Du brauchst git, Node 22 oder neuer und pnpm 10 oder neuer. Jedes Vue-3-Projekt funktioniert — Nuxt, Vite oder reines Vue.
Schritt 1 — Den Code holen
git clone https://github.com/LilyDesignSystem/lily-design-system
cd lily-design-system/lily-design-system-vue-headless
pnpm install
pnpm test # vitest + @testing-library/vue
pnpm run storybook # browse all 571 components
Die Komponenten sind flache Dateien in components/ —
Button.vue, TextInput.vue — jede mit ihrem Test, ihrer Story und ihrer Dokumentation daneben. Kopiere die benötigten Dateien, oder hole das Repo.
Schritt 2 — Deine erste Komponente
<script setup>
import Button from "lily-design-system-vue-headless/components/Button.vue";
</script>
<template>
<Button @click="save">Save</Button>
</template>
Rendert <button class="button" type="button">. Die Props entsprechen den anderen Frameworks: type, disabled,
pressed, label, plus Attribut-Fall-through für alles andere.
Schritt 3 — Ein kleines Formular zusammensetzen
<script setup>
import { ref } from "vue";
import Form from ".../components/Form.vue";
import Field from ".../components/Field.vue";
import TextInput from ".../components/TextInput.vue";
import Button from ".../components/Button.vue";
const name = ref("");
</script>
<template>
<Form @submit="handleSubmit">
<Field label="Full name" required>
<TextInput id="name" label="Full name" v-model="name" required />
</Field>
<Button type="submit">Save</Button>
</Form>
</template>
Field nimmt das sichtbare label als eigene Prop statt als verschachtelte Label-Komponente — gib es einmal an, bei
Fieldund TextInputvon
label liefert den zugänglichen Namen.
Geprüft am 2026-08-29: ein früherer Entwurf verschachtelte eine separate Label innerhalb von Field, was
zwei Labels (eines leer) rendert, weil Field bereits ein eigenes aus dem label -Prop — durch Kompilieren des exakten Snippets entdeckt. Die
Die zusammengesetzte Kontaktformular-Route
ist dasselbe Muster, getestet mit echten e2e- und axe-Tests.
TextInput verwendet defineModel, daher funktioniert ein einfaches
v-model sofort.
Prüfe deine Arbeit: Starte die App, und das Formular sieht schlicht aus — genau wie beabsichtigt: Die Gestaltung kommt noch. Drücke Tab: Der Fokus wandert durch jedes Bedienelement, das Label wird angesagt und das Absenden funktioniert. Das Verhalten ist fertig; das Aussehen gehört dir und kommt als Nächstes.
Schritt 4 — Gestalten
Gestalte die Klassen-Hooks — .button, .text-input,
.label, .field — in deinem Stylesheet, oder binde ein fertiges Theme ein in index.html / nuxt.config:
<link rel="stylesheet" href="/themes/nord.css" />
Schritt 5 — Alles in Aktion sehen
Nuxt-Beispiel-App ist der vollständige Katalog gestaltet und demonstriert, mit Playwright-e2e und einer axe-core-Baseline:
git clone https://github.com/LilyDesignSystem/lily-design-system
cd lily-design-system/lily-design-system-vue-nuxt-examples
pnpm install && pnpm run dev
Nächste Schritte
- Theming — Umschalten zur Laufzeit mit dem Vue-Helper theme-picker.
- Einstellungs-Helper — Sprache und Textgröße.
- Komponentenkatalog — Props, ARIA und Tastatur pro Komponente.
Fragen unterwegs? Die Hilfeseite steckt voller Antworten — und wenn ein Schritt klarer sein könnte, sag es uns und wir verbessern das Tutorial gern.