Skip to content

参考

基于 storybook.js.org 官方文档编写,对照 Storybook 10 稳定版

速查

  • 三配置文件main.ts(项目行为)/ preview.ts(Canvas 全局)/ manager.ts(UI 主题)
  • 三作用域:global(preview)→ component(meta)→ story,下层覆盖上层
  • CSF 3 三件套default export(meta)+ 多个 named export(story)+ Meta/StoryObj 类型
  • Essentials 八件:Actions / Controls / Backgrounds / Viewport / Measure / Outline / Highlight / Toolbars
  • 核心 addonaddon-a11y(axe-core)/ addon-docs(autodocs)/ addon-interactions + addon-vitest(play 测试)
  • Actions 三选一fn()(推荐,可 spy)/ action()(仅日志)/ argTypesRegex(play 不可用)
  • a11y 三档test = off / todo(默认)/ error(CI 失败)
  • autodocstags:['autodocs'] 全局 / tags:['!autodocs'] 单组件关
  • 属性隐藏table:{disable:true} 完全移除;control:false 仅关控件保留文档行
  • Storybook 10(2025-10):ESM-only 包分发;CSF Factories 实验性(defineMain/definePreview/preview.meta/meta.story)
  • 本仓库版本packages/ui@storybook/vue3-vite ^10.3.6
  • 完整说明见 入门 / 核心指南

CSF 语法速查

CSF 2 vs CSF 3

维度CSF 2(旧)CSF 3(推荐)
Story 写法函数式 (args) => <Comp {...args}/>对象式 { args: {...} }
复用Template.bind({}) + 逐字段赋值展开运算符 { args: { ...Default.args, size:'lg' } }
类型 APIComponentMeta / ComponentStoryMeta / StoryObj
title必须手写可省略,按文件路径推断
render默认隐式可选,覆盖默认渲染
升级已过时codemod:npx storybook migrate csf-2-to-3

Meta(默认导出)字段

字段必需类型作用
component组件驱动 props 表 / docgen
titlestring侧边栏分组(CSF3 可省略自动推断)
tagsstring[]autodocs / !dev / test-only
argsobject全 story 共用的默认 args
argTypesobject元数据(控件类型 / 选项 / 描述 / 表)
decoratorsfn[]组件级包装函数
parametersobject组件级参数(layout / backgrounds / a11y 等)
renderfn覆盖默认渲染
includeStoriesregex/string[]哪些导出当 story 加载
excludeStoriesregex/string[]哪些导出不加载

Story(命名导出)字段

字段作用
argsstory 专属输入(覆盖 meta.args)
argTypesstory 专属元数据
decoratorsstory 专属包装函数
parametersstory 专属参数
render自定义渲染
name覆盖 UI 显示名(默认按导出名 startCase)
play交互测试函数 async ({ canvas, userEvent }) => {}
tags标签(如 !dev 不在侧边栏显示)
loaders异步加载 mock 数据

loaders(异步数据)

ts
export const WithUser: Story = {
  loaders: [
    async () => {
      const user = await fetch("/api/user").then(r => r.json());
      return { user };
    },
  ],
  render: (args, { loaded: { user } }) => ({
    props: { ...args, user },
  }),
};

Control 类型族完整表

类型适配 prop 类型可选配置典型用例
booleanbooleandisabled / loading
numbernumbermin/max/stepcount
rangenumbermin/max/stepopacity / progress
objectobjectstyle / config
fileFile/stringacceptavatar / logo
radiostring/number(单选)optionssize(块状)
inline-radio同上optionssize(行内)
checkarray(多选)optionstags(块状)
inline-check同上optionstags(行内)
selectstring/number(下拉)optionsvariant
multi-selectarray(下拉多选)optionsselected
textstringlabel
colorstring(hex/rgb)presetColorsbg / color
datestring(ISO)birthday
null自动推断
false关闭控件

Addons 完整清单

Essentials(@storybook/addon-essentials 一包八个)

插件作用禁用方式
Actions捕获事件回调features: { actions: false }
Controls自动参数控件parameters: { controls: { disable: true } }
Backgrounds切换背景色features: { backgrounds: false }
Viewport响应式视口parameters: { viewport: { disable: true } }
Measure测量元素features: { measure: false }
Outline元素轮廓features: { outline: false }
HighlightDOM 高亮features: { highlight: false }
Toolbars全局工具栏

测试 / 质量类

插件包名作用
A11y@storybook/addon-a11yaxe-core 无障碍检查
Interactions@storybook/addon-interactionsplay 函数调试面板
Vitest@storybook/addon-vitestVitest 集成跑 stories
Test Runner@storybook/test-runner独立进程跑 stories 测试
Storyshots@storybook/addon-storyshotsJest snapshot(旧)

文档 / 协作类

插件包名作用
Docs@storybook/addon-docsautodocs + MDX
Links@storybook/addon-linksstory 间跳转
Designstorybook-addon-designs嵌入 Figma 设计稿
Changelogstorybook-changelog显示 CHANGELOG

主题 / 样式类

插件包名作用
Themesstorybook-addon-themes主题切换(与 globalTypes.theme 类似)
Styles@storybook/addon-styling(已更名)SCSS/Tailwind/UnoCSS 集成

数据 / Mock 类

插件包名作用
GraphQLstorybook-addon-apolloApollo Client mock
Mock Datestorybook-mock-date-decorator时间 mock

配置项速查

main.ts(StorybookConfig)字段

字段类型作用
storiesstring[]story 文件 glob
addonsstring[]/object[]插件清单
framework.namestring@storybook/{framework}-{builder}
framework.optionsobjectbuilder 选项
viteFinalfn注入 Vite 配置
webpackFinalfn注入 Webpack 配置
staticDirsstring[]静态资源
docsobjectautodocs: 'tag' | false
featuresobject实验特性
typescriptobjectTS 配置(check / reactDocgen)
coreobjectdisableTelemetry
refsobject跨项目 stories 引用
envobject注入 process.env
loglevelstringverbose/debug/info/warn/error/error

preview.ts(Preview)字段

字段类型作用
parametersobject全局参数(controls/backgrounds/a11y/viewport/layout)
globalTypesobject工具栏全局注解(theme 等)
decoratorsfn[]全局包装函数
tagsstring[]autodocs
initialGlobalsobjectglobalTypes 初始值
argsobject全局默认 args
argTypesobject全局元数据(隐藏框架噪声)
loadersfn[]全局异步数据加载
applyDecoratorsfn自定义 decorator 组合

parameters 常用项

参数作用
layoutpadded(默认)/ centered / fullscreen
controls.matchers自动推断 color/date 的正则
controls.hideNoControlsWarning关闭「无控件」警告
backgrounds.default默认背景名
backgrounds.values背景列表(name/value)
viewport.default默认视口
viewport.viewports视口列表
a11y.testoff/todo/error
a11y.config.rules局部禁用规则
docs.page自定义文档页(mdx)

a11y 配置详解

ts
parameters: {
  a11y: {
    element: "#root", // 检查范围
    config: {
      rules: [
        { id: "color-contrast", enabled: false }, // 局部禁用
      ],
    },
    options: {
      runOnly: {
        type: "tag",
        values: ["wcag2a", "wcag2aa"], // 仅检查 WCAG 2.x A/AA
      },
    },
    manual: false, // true = 完全手动(不推荐)
  },
}

test 三值行为

行为用途
off完全不跑调试临时关
todo(默认)跑 + 显示但不失败渐进式引入
error跑 + 违规即失败CI 防回归

play 函数 API

ts
import { expect, fn, userEvent, within, waitFor } from "@storybook/test";

export const Demo: Story = {
  args: { onSubmit: fn() }, // 注入 spy
  play: async ({ canvasElement, args, step, loaded, globals }) => {
    const canvas = within(canvasElement); // Testing Library 风格
    await step("输入邮箱", async () => {
      await userEvent.type(canvas.getByLabelText("邮箱"), "a@b.com");
    });
    await step("提交", async () => {
      await userEvent.click(canvas.getByRole("button", { name: /提交/i }));
    });
    await waitFor(() => {
      expect(args.onSubmit).toHaveBeenCalledWith({ email: "a@b.com" });
    });
  },
};

play 参数

字段类型作用
canvasElementHTMLElementCanvas 根节点(给 within)
argsobjectstory 的 args(含 spy)
stepfn分步(在 UI 里展开)
loadedobjectloaders 返回的数据
globalsobjectglobalTypes 当前值

视觉回归对比

维度HTML 快照(jest snapshot)Chromatic
比对对象渲染后的 HTML 标记用户实际看到的像素
重构误报改 className / 移位空格都触发不影响视觉就不报
格式化误报Prettier 重排触发不触发
跨浏览器不支持Chrome/Firefox/Safari/Edge
视口 / 主题不支持支持
Review 工作流git diffWeb 界面(接受/拒绝)
成本免费(本地)商业化(免费档有限)
信噪比

版本变化

Storybook 10.0(2025-10,当前主线)

  • ESM-only 包分发:v9 已减 50% 安装体积,10 再降 29%
  • CSF 3 仍是默认推荐:对象式 + Meta/StoryObj + 自动 title 推断
  • CSF Factories 实验性(下一代):defineMaindefinePreviewpreview.metameta.story 链式工厂
    • 端到端类型安全(含 addon parameters/globals 类型推断)
    • subpath imports(#.storybook/preview
    • React 框架完整支持,Vue/Angular/Svelte/Web Components 推进中(API 可能变化)
    • 同一文件不能 CSF 3 与 Factories 混用,但项目内可分文件混用
  • Angular-vite 框架(preview)
  • CSF 1/2/3 不会被废弃

Storybook 9(2024)

  • 安装体积减 50%
  • Onboarding UI 升级
  • Test provider API 改进

Storybook 8(2024)

  • 引入 CSF Factories 早期实验
  • Test provider API
  • Vite builder 默认推荐
  • Vue 3 / Svelte 5 / Next.js 14 支持

Storybook 7(2023)

  • CSF 3 成默认推荐
  • 新型框架 API(framework 字段为对象)
  • Vite builder 正式
  • Interactions addon
  • Component Testing

框架与 Builder 对照

框架包名Builder
Vue 3@storybook/vue3-viteVite
Vue 3@storybook/vue3-webpack5(旧)Webpack
React@storybook/react-viteVite
React@storybook/react-webpack5Webpack
Angular@storybook/angularWebpack
Angular@storybook/angular-vite(10 preview)Vite
Svelte@storybook/svelte-vite / sveltekitVite
Web Components@storybook/web-components-viteVite
Preact@storybook/preactVite
Solid@storybook/solidVite
Next.js@storybook/nextjsWebpack
Remix@storybook/remix-viteVite

本仓库用 @storybook/vue3-vite ^10.3.6

与相邻工具的边界

工具边界
Vitest / Jest纯逻辑(reducer/util/纯函数)单元测试
Vue Test Utils / Testing Library组件渲染 + 用户事件断言(Storybook 的 play 函数等价能力)
Cypress / PlaywrightE2E:整页 / 跨页 / 真实后端的用户流
Ladle / StoryshotsStorybook 的本地化轻量替代
StyleguidistReact 专用组件文档(同生态位)
dumiVue/React 组件文档(中文生态)
Figma / Design Tokens上游设计来源(Storybook 消费)
packages/ui 构建配置组件实现与打包(Vite library mode / tsup),Storybook 只消费

官方资源