如何让 Storybook 自动生成 argTypes 与 Controls:跨框架 Props 声明实操指南
【免费下载链接】storybookStorybook is the industry standard workshop for building, documenting, and testing UI components in isolation项目地址: https://gitcode.com/GitHub_Trending/st/storybook
本指南以 Storybook 的跨框架 Button 示例为切入点,讲清 React、Angular、Vue、Svelte、Web Components 各自的 Props 声明如何被 docgen 解析,最终自动产出 argTypes 与 Controls,让你把组件写规范这一步就"顺手"拿到文档面板。
官方教程讲"第一个 Story"时,总是先给出一段带完整 Props 元信息的组件实现,再进入.stories文件。这些示例的源头都在 docs/_snippets/ 目录:button-component-with-proptypes.md存着组件实现本身,同一个 Button(一个布尔开关加一段文案)被拆成 6 份代码,对应 6 种框架写法。
💡 结论先行:Controls 面板的智能程度,由组件侧的 Props 声明决定
argTypes 是 Storybook 自动推导出来的参数元数据,描述每个属性的名称、类型、默认值、描述文字,以及 Controls 该渲染成开关还是文本框。它的完整结构可参考 docs/_snippets/storybook-generated-argtypes.md:
const argTypes = { label: { type: { name: 'string', required: false }, defaultValue: 'Hello', description: 'demo description', control: { type: 'text' }, }, };这个对象里的每个字段都有明确出处:
type来自你在组件里写的类型声明——boolean渲染成开关,string渲染成文本框;description来自字段上方的 JSDoc 注释,成为 ArgsTable 与 Controls 里的说明文字;defaultValue来自组件侧的默认值,进入参数表的 Default 列。
换句话说,你在组件代码里敲下的类型和注释,正是文档系统的输入数据。
🔄 argTypes 是怎么自动生成的:一条四步数据流
整条链路四步,各框架差别只在第二步的"解析工具",入口和出口完全一致:
- 声明 Props:按框架约定写出属性(速查表见下节);
- docgen 静态解析:不执行代码,只读源码,抽出属性名、类型、默认值、注释;
- 产出 argTypes:解析结果合并成结构化对象,挂到 story 的 meta 上;
- 面板渲染:Docs 页的参数表与 Canvas 里的 Controls 面板,都依据这个对象绘制。
各框架的 docgen 工具链,仓库依赖文件里都能查到实证:
- React:code/frameworks/react-vite/ 依赖
react-docgen与@joshwooding/vite-plugin-react-docgen-typescript,Webpack 侧则用 code/presets/react-webpack/ 中的@storybook/react-docgen-typescript-plugin; - Angular:借
@storybook/angular-compodoc跑 Compodoc,code/frameworks/angular/build-schema.json 提供compodoc与compodocArgs配置项;code/frameworks/angular-vite/ 则导出内置的./internal/docgen-worker; - Vue 3:code/renderers/vue3/ 依赖
vue-docgen-api,code/renderers/vue3/src/docgen/build-docgen.ts 负责把__docgenInfo转成 argTypes; - Svelte:
@storybook/addon-svelte-csf的defineMeta读取export let变量上的注释; - Web Components(Lit):直接解析类上方的 JSDoc(
@prop、@summary、@tag)与@property()装饰器。
🧭 跨框架 Props 声明对照表:六个框架各写在哪
以同一个 Button(布尔isDisabled+ 文本content)为例,各框架写法汇总如下:
| 框架 | 声明位置 | 类型载体 | 默认值写法 | 必填语义 | 描述来源 |
|---|---|---|---|---|---|
| React (JS) | Button.propTypes | PropTypes.bool/string+isRequired | 无,由调用方传入 | isRequired | 属性上方 JSDoc |
| React (TS) | ButtonPropsinterface | TS 类型 +React.FC泛型 | 解构默认值 | ?可选标记 | 字段上方 JSDoc |
| Angular | @Input()字段 | 字段的 TS 类型 | 字段初值 | @required注释 | 字段上方 JSDoc |
| Vue 3 (JS/TS) | props选项 | type+ TS 推导(defineComponent) | default | required: true | 字段上方注释 |
| Svelte | export let变量 | Svelte 编译器 | 变量初值 | @required标记 | 变量上方 JSDoc |
| Web Components | static properties/@property() | Lit 装饰器 + TS 类型 | 构造函数 / 字段初值 | 靠默认值约定 | 类上方@propJSDoc |
React TS 版最能体现"一份声明两用",interface 既承担类型,又承担文档锚点:
export interface ButtonProps { /** Checks if the button should be disabled */ isDisabled: boolean; /** The display content of the button */ content: string; }所有框架共用一条铁律:类型声明与 JSDoc 注释写在同一个字段上——前者决定控件形态,后者变成面板说明。缺任何一边,面板对应栏目都会空着。
⚠️ 四个让 argTypes"缺失"或"说谎"的坑
- 命名不统一。React / Angular / Web Components 示例用
isDisabled,Svelte 示例改用disabled,Vue 示例则把文案属性叫label。写 story 时 args 的键必须与组件属性名逐字一致,对不上号,控件就改不动组件。 - 必填与默认值并存。Vue 示例里
required: true与default同时出现,语义上其实是冗余的;TS 版示例便把required去掉了。二者选其一,并保持项目内一致。 - 注释位置错了等于没写。注释必须紧贴并悬挂在对应字段上方——
propTypes项上方、interface 字段上方、@Input()上方或类上方。写在函数体里、或与代码同行,docgen 都匹配不到该属性。 - Svelte 片段的闭合标签。示例第 90 行写作
<script/>,真实 Svelte 组件里脚本标签应闭合为</script>,否则编译器直接报错。
另外两条命名小规则也值得留意:Angular 的 selector 应使用至少两个词(如my-button),避免撞上原生标签;Vue 的name: 'button'这种单词名,会被vue/multi-word-component-namesESLint 规则告警。
🔗 组件写完后:第一个 Story 的 meta 只需一行衔接
在Button.stories文件的 meta 中声明component: Button,Storybook 就把组件元数据与这组 story 关联起来:
const meta = { component: Button, parameters: { actions: { argTypesRegex: '^on.*' } }, } satisfies Meta<typeof Button>;- Web Components 的元素按名字注册,meta 里改用字符串:
component: 'demo-button'(跨框架完整写法见 docs/_snippets/button-story-matching-argtypes.md); argTypesRegex: '^on.*'会把以on开头的属性自动登记到 Actions 面板,方便记录onClick这类事件(背景见 docs/essentials/actions.mdx);- 官方教程入口:docs/get-started/whats-a-story.mdx 与 docs/writing-stories/args.mdx。
关键回顾
- Props 声明是 Storybook 产出 argTypes 的唯一数据来源:类型定控件形态,注释成说明文字,默认值进参数表。
- 六个框架写法各异,但都遵守"注释紧贴字段上方"这一条。
- meta 里接上
component之后,Controls 与 Docs 面板便随组件声明自动生效。
【免费下载链接】storybookStorybook is the industry standard workshop for building, documenting, and testing UI components in isolation项目地址: https://gitcode.com/GitHub_Trending/st/storybook
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考