Storybook для компонентов

Storybook — это мощный инструмент для разработки и тестирования компонентов интерфейса в изоляции. Он позволяет создавать отдельные «истории» для каждого компонента, проверять их поведение и внешний вид независимо от основного приложения. В экосистеме Vue.js Storybook обеспечивает быстрый и удобный способ визуальной разработки и документирования UI-компонентов.


Установка и настройка Storybook

Для Vue.js используется официальная интеграция Storybook. Начало работы включает установку через npm или yarn:

npx sb init --type vue3

Эта команда создаёт базовую конфигурацию Storybook, включая папки .storybook и примеры историй в src/stories. Важно убедиться, что версия Vue совместима с используемой версией Storybook (например, Vue 3 с @storybook/vue3).

Конфигурация Storybook хранится в файлах внутри .storybook:

  • main.js — определяет, какие файлы историй загружать, и подключаемые аддоны.
  • preview.js — задаёт глобальные параметры и декораторы, которые применяются ко всем историям.
  • manager.js — настройка интерфейса панели Storybook.

Пример main.js для Vue 3:

module.exports = {
  stories: ['../src/**/*.stories.@(js|ts|jsx|tsx)'],
  addons: ['@storybook/addon-links', '@storybook/addon-essentials'],
  framework: '@storybook/vue3',
};

Создание истории для компонента

История представляет собой отдельный сценарий использования компонента. Структура файла истории обычно следующая:

import MyButton from './MyButton.vue';

export default {
  title: 'Example/MyButton',
  component: MyButton,
  argTypes: {
    label: { control: 'text' },
    disabled: { control: 'boolean' },
  },
};

const Template = (args) => ({
  components: { MyButton },
  setup() {
    return { args };
  },
  template: '<MyButton v-bind="args" />',
});

export const Primary = Template.bind({});
Primary.args = {
  label: 'Primary Button',
  disabled: false,
};

export const Disabled = Template.bind({});
Disabled.args = {
  label: 'Disabled Button',
  disabled: true,
};

Ключевые моменты:

  • title — задаёт путь в панели Storybook.
  • component — подключаемый Vue-компонент.
  • argTypes — настройка контролов для динамического изменения свойств.
  • Template — функция, создающая компонент с привязкой к аргументам (args).

Использование .bind({}) позволяет создавать несколько вариаций одной истории без дублирования кода.


Аргументы (Args) и Controls

Система аргументов в Storybook позволяет интерактивно изменять свойства компонента прямо в интерфейсе. Аргументы передаются через v-bind и управляются панелью Controls. Это облегчает тестирование различных состояний компонента без изменения исходного кода.

Пример настройки аргументов для поля ввода:

argTypes: {
  placeholder: { control: 'text' },
  value: { control: 'text' },
  readonly: { control: 'boolean' },
}

Декораторы и глобальные параметры

Декораторы позволяют оборачивать истории в дополнительные контексты. Например, можно добавить глобальные стили, провайдеры состояний или темы:

export const decorators = [
  (story) => ({
    components: { story },
    template: '<div style="padding: 20px; background: #f0f0f0;"><story/></div>',
  }),
];

Глобальные параметры задаются в preview.js:

export const parameters = {
  actions: { argTypesRegex: '^on[A-Z].*' },
  controls: { expanded: true },
};

Аддоны для Vue Storybook

Аддоны расширяют возможности Storybook. Популярные аддоны:

  • @storybook/addon-essentials — набор базовых инструментов (Actions, Controls, Docs).
  • @storybook/addon-a11y — проверка доступности компонентов.
  • @storybook/addon-links — создание навигации между историями.
  • @storybook/addon-docs — генерация документации на основе историй.

Использование аддонов позволяет превратить Storybook в полноценный инструмент для визуального тестирования и документирования компонентов.


Интеграция с Vuex и Vue Router

Компоненты часто зависят от состояния приложения или маршрутов. Storybook позволяет подключать Vuex и Vue Router через декораторы:

import { createStore } from 'vuex';
import { createRouter, createWebHistory } from 'vue-router';
import App from './App.vue';

const store = createStore({
  state: { count: 0 },
  mutations: { increment(state) { state.count++; } },
});

const router = createRouter({
  history: createWebHistory(),
  routes: [{ path: '/', component: App }],
});

export const decorators = [
  (story) => ({
    components: { story },
    setup() { return { store, router }; },
    template: '<story />',
  }),
];

Такой подход позволяет тестировать компонент в условиях максимально приближенных к реальному приложению.


Ведение и организация историй

Для больших проектов важно структурировать истории:

  • По компонентам: Button, Input, Modal.
  • По функциональным блокам: Form Elements, Navigation.
  • С использованием поддиректорий для сложных наборов компонентов.

Файлы историй могут иметь расширение .stories.js или .stories.ts, что позволяет использовать TypeScript для типизации аргументов и улучшенной интеграции с IDE.


Документация и Storybook Docs

Storybook Docs автоматически генерирует документацию на основе историй и JSDoc-комментариев. Это особенно полезно для командной разработки:

/**
 * Компонент кнопки для отправки формы
 *
 * @param {string} label - Текст на кнопке
 * @param {boolean} disabled - Состояние блокировки кнопки
 */
export default {
  title: 'Example/MyButton',
  component: MyButton,
};

Панель Docs отображает свойства компонента, примеры использования и доступные события, упрощая коммуникацию между разработчиками и дизайнерами.


Storybook превращает процесс разработки Vue-компонентов в визуально интерактивный и модульный workflow. Правильная настройка, использование аргументов, декораторов и аддонов делает его незаменимым инструментом для поддерживаемых и хорошо документированных интерфейсов.