Руководство по Vue
Однофайловые компоненты Vue 3 с типизированными props, defineModel
двусторонней привязкой и пробросом v-bind="$attrs" .
Что вы построите
Небольшая контактная форма — поле с меткой, кнопка отправки, v-model
привязка, реальное поведение клавиатуры и программы чтения с экрана — сначала голая, затем оформленная, примерно за 10 минут.
Прежде чем начать
Вам понадобятся git, Node 22 или новее и pnpm 10 или новее. Подойдёт любой проект Vue 3 — Nuxt, Vite или обычный Vue.
Шаг 1 — Получите код
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
Компоненты — это плоские файлы в components/ —
Button.vue, TextInput.vue — у каждого рядом его тест, story и документация. Скопируйте нужные файлы или подтяните репозиторий.
Шаг 2 — Ваш первый компонент
<script setup>
import Button from "lily-design-system-vue-headless/components/Button.vue";
</script>
<template>
<Button @click="save">Save</Button>
</template>
Отображает <button class="button" type="button">. Props соответствуют другим фреймворкам: type, disabled,
pressed, label, плюс проброс атрибутов для всего остального.
Шаг 3 — Составьте небольшую форму
<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 принимает видимую label как собственный prop, а не как вложенный компонент метки — передайте её один раз, на
Fieldи TextInputиз
label обеспечивает доступное имя.
Проверено 2026-08-29: в более раннем черновике отдельный компонент Label внутри Field, что отображало
две метки (одну пустую), потому что Field уже отображает свою собственную из входа label prop — обнаружено компиляцией точного фрагмента. Маршрут
Составной маршрут контактной формы
— тот же шаблон, проверенный настоящими тестами e2e и axe.
TextInput использует defineModel, поэтому обычный
v-model работает сразу.
Проверьте свою работу: запустите приложение, и форма выглядит голой — именно так, как задумано: оформление ещё впереди. Нажмите Tab: фокус проходит через каждый элемент управления, метка озвучивается, а отправка работает. Поведение готово; внешний вид за вами, и это следующий шаг.
Шаг 4 — Оформите её
Оформите крючки классов — .button, .text-input,
.label, .field — в вашей таблице стилей, или подключите готовую тему в index.html / nuxt.config:
<link rel="stylesheet" href="/themes/nord.css" />
Шаг 5 — Посмотрите, как всё работает
Пример приложения Nuxt — это полный каталог в оформленном виде и с демонстрацией, с Playwright e2e и базовой линией axe-core:
git clone https://github.com/LilyDesignSystem/lily-design-system
cd lily-design-system/lily-design-system-vue-nuxt-examples
pnpm install && pnpm run dev
Дальнейшие шаги
- Темы — переключение во время выполнения с помощником theme-picker для Vue.
- Помощники настроек — язык и размер текста.
- Каталог компонентов — свойства, ARIA и клавиатура для каждого компонента.
Есть вопросы по ходу дела? Страница справки полна ответов — а если какой-то шаг можно сделать яснее, сообщите нам и мы с радостью улучшим руководство.