文档
Storybook Docs

Storybook for Vue & Vite

Storybook for Vue & Vite 是一个 框架,可轻松为使用 Vite 构建的 Vue 应用程序单独开发和测试 UI 组件。它包含

  • 🏎️ 预打包以提高性能
  • 🪄 无需配置
  • 🧠 完整的文档生成
  • 💫 等等!

要求

  • Vue ≥ 3
  • Vite ≥ 5.0

入门

在没有 Storybook 的项目中

在 Vue 项目的根目录下运行此命令后,请按照提示操作

npm create storybook@latest

更多关于 Storybook 入门的信息。

在已有 Storybook 的项目中

此框架旨在与 Storybook 7+ 配合使用。如果您尚未升级到 v7,请使用此命令进行升级。

npx storybook@latest upgrade

自动迁移

运行上述 upgrade 命令时,您应该会收到一个提示,询问您是否要迁移到 @storybook/vue3-vite,它应该会为您处理一切。如果自动迁移不适用于您的项目,请参阅下面的手动迁移。

手动迁移

首先,安装框架。

npm install --save-dev @storybook/vue3-vite

然后,更新您的 .storybook/main.js|ts 以更改框架属性。

.storybook/main.ts
import type { StorybookConfig } from '@storybook/vue3-vite';
 
const config: StorybookConfig = {
  // ...
  framework: '@storybook/vue3-vite', // 👈 Add this
};
 
export default config;

扩展 Vue 应用

Storybook 会创建一个 Vue 3 应用来预览您的组件。当使用全局自定义组件(app.component)、指令(app.directive)、扩展(app.use)或其他应用方法时,您需要在 ./storybook/preview.js|ts 文件中进行配置。

因此,Storybook 提供了一个从该包导出的 setup 函数。此函数接收您的 Storybook 实例作为回调,您可以通过它进行交互并添加自定义配置。

.storybook/preview.js|ts
import { setup } from '@storybook/vue3-vite';
 
setup((app) => {
  app.use(MyPlugin);
  app.component('my-component', MyComponent);
  app.mixin({
    // My mixin
  });
});

使用 vue-component-meta

vue-component-meta 仅在 Storybook ≥ 8 中可用。目前是选择加入的,但在未来的 Storybook 版本中将成为默认选项。

vue-component-meta 是由 Vue 团队维护的一个工具,用于从 Vue 组件中提取元数据。Storybook 可以使用它来为您的故事和文档生成 控件。它是 vue-docgen-api 的一个功能更全面的替代方案,推荐大多数项目使用。

如果您想使用 vue-component-meta,可以在您的 .storybook/main.js|ts 文件中进行配置

.storybook/main.ts
import type { StorybookConfig } from '@storybook/vue3-vite';
 
const config: StorybookConfig = {
  framework: {
    name: '@storybook/vue3-vite',
    options: {
      docgen: 'vue-component-meta',
    },
  },
};
 
export default config;

vue-component-meta 带来了许多好处,并启用了更多的文档功能,例如:

支持多种组件类型

vue-component-meta 支持所有类型的 Vue 组件(包括 SFC、函数式、Composition/Options API 组件),来自 .vue.ts.tsx.js.jsx 文件。

它还支持默认和命名组件导出。

Props 描述和 JSDoc 标签注释

要描述一个 prop,包括标签,您可以在组件的 props 定义中使用 JSDoc 注释

YourComponent.vue
<script setup lang="ts">
  interface MyComponentProps {
    /** The name of the user */
    name: string;
    /**
      * The category of the component
      *
      * @since 8.0.0
      */
    category?: string;
  }
 
  withDefaults(defineProps<MyComponentProps>(), {
    category: 'Uncategorized',
  });
</script>

上面的 props 定义将生成以下控件

Controls generated from props

事件类型提取

要为发出的事件提供类型,您可以在组件的 defineEmits 调用中使用 TypeScript 类型(包括 JSDoc 注释)

YourComponent.vue
<script setup lang="ts">
  type MyChangeEvent = 'change';
 
  interface MyEvents {
    /** Fired when item is changed */
    (event: MyChangeEvent, item?: Item): void;
    /** Fired when item is deleted */
    (event: 'delete', id: string): void;
    /** Fired when item is upserted into list */
    (e: 'upsert', id: string): void;
  }
 
  const emit = defineEmits<MyEvents>();
</script>

这将生成以下控件

Controls generated from events

插槽类型提取

插槽类型会从您的组件定义中自动提取,并在控件面板中显示。

YourComponent.vue
<template>
  <slot :num="123"></slot>
  <br />
  <slot name="named" str="str"></slot>
  <br />
  <slot name="no-bind"></slot>
  <br />
  <slot name="vbind" v-bind="{ num: 123, str: 'str' }"></slot>
</template>
 
<script setup lang="ts"></script>

如果您使用 defineSlots,您可以在组件的 slots 定义中使用 JSDoc 注释来描述每个插槽

defineSlots<{
  /** Example description for default */
  default(props: { num: number }): any;
  /** Example description for named */
  named(props: { str: string }): any;
  /** Example description for no-bind */
  noBind(props: {}): any;
  /** Example description for vbind */
  vbind(props: { num: number; str: string }): any;
}>();

上面的定义将生成以下控件

Controls generated from slots

公开的属性和方法

您组件公开的属性和方法会自动提取并显示在 控件 面板中。

YourComponent.vue
<script setup lang="ts">
  import { ref } from 'vue';
 
  const label = ref('Button');
  const count = ref(100);
 
  defineExpose({
    /** A label string */
    label,
    /** A count number */
    count,
  });
</script>

上面的定义将生成以下控件

Controls generated from exposed properties and methods

覆盖默认配置

如果您正在处理一个依赖 tsconfig references 来链接到其他现有配置文件(例如 tsconfig.app.jsontsconfig.node.json)的项目,我们建议您更新您的 .storybook/main.js|ts 配置文件并添加以下内容

.storybook/main.ts
import type { StorybookConfig } from '@storybook/vue3-vite';
 
const config: StorybookConfig = {
  framework: {
    name: '@storybook/vue3-vite',
    options: {
      docgen: {
        plugin: 'vue-component-meta',
        tsconfig: 'tsconfig.app.json',
      },
    },
  },
};
 
export default config;

这不是 Storybook 的限制,而是 vue-component-meta 的工作方式。有关更多信息,请参阅相应的 GitHub issue

否则,您可能会遇到组件类型/描述缺失或无法解析的导入别名,例如 @/some/import

故障排除

Storybook 不适用于我的 Vue 2 项目

Vue 2 已于 2023 年 12 月 31 日进入生命周期结束 (EOL),不再由 Vue 团队维护。因此,Storybook 不再支持 Vue 2。我们建议您将项目升级到 Vue 3,Storybook 完全支持 Vue 3。如果不行,您仍然可以通过安装最新版本的 Storybook 7 来使用 Storybook 和 Vue 2,命令如下:

npx storybook@^7 init

API

选项

如果需要,您可以传递一个选项对象进行其他配置

.storybook/main.ts
import type { StorybookConfig } from '@storybook/vue3-vite';
 
const config: StorybookConfig = {
  framework: {
    name: '@storybook/vue3-vite',
    options: {
      docgen: 'vue-component-meta',
    },
  },
};
 
export default config;

builder

类型:Record<string, any>

配置框架构建器的选项。对于此框架,可用选项可以在Vite 构建器文档中找到。

docgen

类型: 'vue-docgen-api' | 'vue-component-meta' | boolean

默认值: 'vue-docgen-api'

首次出现: 8.0

选择在生成组件控件时使用哪个 docgen 工具。有关更多信息,请参阅 使用 vue-component-meta

设置为 false 以完全禁用 docgen 处理,以提高构建性能。

.storybook/main.ts
import type { StorybookConfig } from '@storybook/vue3-vite';
 
const config: StorybookConfig = {
  framework: {
    name: '@storybook/vue3-vite',
    options: {
      docgen: false, // Disable docgen for better performance
    },
  },
};
 
export default config;
何时禁用 docgen

禁用 docgen 可以提高大型项目的构建性能,但 argTypes 将不会自动推断,这将阻止 Controlsdocs 等功能正常工作。要使用这些功能,您需要 手动定义 argTypes