Vue-handledning

Vue 3-enfilskomponenter med typade props, defineModel tvåvägsbindning och v-bind="$attrs" -genomströmning.

Det här bygger du

Ett litet kontaktformulär — fält med etikett, skicka-knapp, v-model -bindning, verkligt tangentbords- och skärmläsarbeteende — först naket, sedan formgivet, på ungefär 10 minuter.

Innan du börjar

Du behöver git, Node 22 eller senare och pnpm 10 eller senare. Alla Vue 3-projekt fungerar — Nuxt, Vite eller vanlig Vue.

Steg 1 — Hämta koden

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

Komponenterna är platta filer i components/ — Button.vue, TextInput.vue — var och en med sitt test, sin story och sin dokumentation bredvid. Kopiera de filer du behöver, eller hämta förvaret.

Steg 2 — Din första komponent

<script setup>
import Button from "lily-design-system-vue-headless/components/Button.vue";
</script>

<template>
  <Button @click="save">Save</Button>
</template>

Renderar <button class="button" type="button">. Propsen motsvarar de andra ramverken: type, disabled, pressed, label, plus attributgenomströmning för allt annat.

Steg 3 — Sätt ihop ett litet formulär

<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 tar den synliga label som sin egen prop i stället för en nästlad etikettkomponent — skicka den en gång, på Fieldoch TextInputfrån label ger det tillgängliga namnet.

Verifierat 2026-08-29: ett tidigare utkast nästlade en separat Label inuti Field, vilket renderar två etiketter (en tom) eftersom Field redan renderar sin egen från label -prop — upptäckt genom att kompilera det exakta kodavsnittet. Rutten Den sammansatta kontaktformulärsrutten är samma mönster, prövat med riktiga e2e- och axe-tester.

TextInput använder defineModel, så en vanlig v-model fungerar direkt.

Kontrollera ditt arbete: kör appen så ser formuläret kargt ut — precis som tänkt: formgivningen återstår. Tryck på Tab: fokus flyttas genom varje kontroll, etiketten läses upp och inskickning fungerar. Beteendet är klart; utseendet är ditt och kommer härnäst.

Steg 4 — Formge det

Formge klasskrokarna — .button, .text-input, .label, .field — i din stilmall, eller länka ett färdigt tema i index.html / nuxt.config:

<link rel="stylesheet" href="/themes/nord.css" />

Steg 5 — Se allt fungera

Exempelappen Nuxt är hela katalogen formgiven och demonstrerad, med Playwright e2e och en axe-core-baslinje:

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ästa steg

Frågor på vägen? Hjälpsidan är full av svar — och om ett steg kan bli tydligare, berätta för oss så förbättrar vi gärna handledningen.