ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

Storybook 实战指南:5 大框架 Button 组件 Props 声明与 argTypes 自动生成避坑手册

Storybook 实战指南:5 大框架 Button 组件 Props 声明与 argTypes 自动生成避坑手册 Storybook 实战指南5 大框架 Button 组件 Props 声明与 argTypes 自动生成避坑手册在 Storybook 里写第一个 Story 时你多半会发现 Controls 面板空空如也、Docs 页没有任何描述——问题往往不在 Story而在组件自身的 Props 声明没写导致 argTypes白话讲面板的属性数据清单自动生成无据可依。本文以仓库 docs/_snippets 中的 Button 示例为主线带你搞懂 React、Angular、Vue、Svelte 与 Web Components 五大框架下 Props 类型与 JSDoc 组件注释该怎么写让 Controls 与 Docs 一启动就亮起来。Controls 面板空空如也先检查你的组件 Props 声明Button.stories.ts里写了component: Button启动之后 Canvas 渲染正常但下方 Controls 面板是空的Docs 的 ArgsTable 也没有描述。这不是 Storybook 的 bug。面板与文档表的数据来源是组件自身的 Props 元信息属性名、类型、默认值、描述。Storybook 不会猜这些字段它靠各框架的 docgen 工具即从源码里读出Props 声明的解析器去读组件源码。你的组件如果是一段没有任何类型、没有任何注释的裸函数解析器就一无所获面板空、描述空。所以顺序不能反——先声明 Props再写 Story这是 Storybook 一切自动化的前提。一条数据链路Props 类型与 JSDoc 注释如何变成 argTypes整条链路分四步① 你在组件 Props 上写类型 JSDoc 注释② 框架的 docgen 解析源码——React 走 react-docgenJS或 react-docgen-typescriptTS interfaceAngular 走 CompodocVue 走 vue-docgen-apiWeb Components 直接读类级 JSDoc③ 解析结果统一成 argTypes 结构④ Docs 的 ArgsTable 与 Controls 面板按 argTypes 渲染。argTypes 长这样完整示例见 storybook-generated-argtypes.mdconst argTypes { label: { name: label, type: { name: string, required: false }, defaultValue: Hello, description: demo description, control: { type: text }, }, };type决定控件形态boolean 渲染成开关、string 渲染成文本框description成为面板里的说明文字defaultValue进 ArgsTable。这三个字段几乎全部来自你写在组件上的类型与注释。 3 步实操从最简 Button 声明到第一个 CSF3 story下面以仓库里最简的 Button 为例走一遍。完整跨框架对照版在 button-component-with-proptypes.md每个框架取核心片段即可。第 1 步选一个框架写最简 Button 声明以 React TypeScript 为例。interface 同时承担类型与文档双重职责export interface ButtonProps { /** Checks if the button should be disabled */ isDisabled: boolean; /** The display content of the button */ content: string; } export const Button: React.FCButtonProps ({ isDisabled false, content }) ( button typebutton disabled{isDisabled}{content}/button );两个字段都有 JSDoc 紧贴在上、都有解构默认值 false/ ——这两点直接决定面板里会多出描述和默认值两列内容。第 2 步启动 Storybook用面板验证 argTypes在项目里运行npx storybook dev打开 Button 的 Controls 页签。看到content是文本框、isDisabled是开关且描述与你写的注释一致说明 docgen 解析成功面板为空则回头检查组件是否被正确引入、注释是否紧贴属性。第 3 步写第一个 CSF3 story 并接入 ActionsCSF3Component Story Format v3就是一个meta默认导出 若干具名 Story 导出的约定。最小 meta 如下跨框架版本见 button-story-matching-argtypes.mdimport type { Meta } from storybook/react; import { Button } from ./Button; const meta { component: Button, parameters: { actions: { argTypesRegex: ^on.* } }, } satisfies Metatypeof Button; export default meta; export const Basic { args: { isDisabled: false, content: Hello } };component: Button让组件元数据与 Story 关联argTypesRegex: ^on.*会把以on开头的属性自动登记进 Actions 面板之后 Canvas 里点一下按钮调用参数就记录下来。 五大框架声明方式速查表一表看清跨框架 Props 声明框架声明写法默认值写法必填表达注释位置ReactJS/TSButton.propTypes/ButtonPropsinterface解构默认值 falseisRequired/ 字段不加?属性上方 JSDocAngular类中Input()字段字段初值JSDocrequired字段上方 JSDocVue 3props选项对象default: Onerequired: trueprop 上方注释Svelteexport let变量 falserequired变量上方 JSDocWeb ComponentsLitstatic properties/property()字段字段初值或构造函数赋值默认值约定类级propJSDoc写法各异填的都是同样的三栏类型、默认值、描述。这些坑会悄悄让文档失效Svelte 脚本标签没闭合官方片段中script/是笔误正确写法是/script照抄会被 Svelte 编译器直接报错Vue 单字组件名告警name: button会触发vue/multi-word-component-namesESLint 规则告警片段里靠注释压制真实项目请用多词名必填与默认值并存default和required: true同时写是自相矛盾的面板的默认值列与必填标记会打架二者只留一个注释没贴紧属性docgen 只提取声明正上方的 JSDoc中间隔了空行、其他语句或注释写错行该属性的description直接丢失Web Components 的prop位置prop必须放在类级 JSDoc 里且tag要与customElements.define的名字一致否则 argTypes 解析为空React双裸函数组件既无propTypes又无 TS interfacedocgen 无米下锅只能退而在 meta 里手写 argTypes。从最简 Button 到完整 Button属性加一点argTypes 长一截两属性版本跑通后可以开始加料。演进方向参考 button-implementation.mdprimary是否页面主操作、size三档尺寸联合类型、onClick点击处理器。TS 版只需在 interface 里继续加字段/** Is this the principal call to action on the page? */ primary?: boolean; /** How large should the button be? */ size?: small | medium | large; /** Optional click handler */ onClick?: () void;面板会跟着类型自动生长primary变开关size联合类型变三选项下拉onClick被argTypesRegex捕获后出现在 Actions 面板。你一行配置都不用写——前提还是那条JSDoc 紧贴字段。加一个属性的成本是一个字段 一条注释收益是 ArgsTable 多一整行、Controls 多一个可用控件这笔账怎么算都划算。收尾把声明写好 免费拿到文档与调试面板沉淀为工程习惯下次在 Storybook 里新增组件动手前先问三个问题每个属性都显式写了类型吗每条属性上方都有 JSDoc 组件注释吗必填与默认值的语义只保留了一种吗三个都是是argTypes 自动生成链路就畅通Controls 立刻可用、Docs 立刻完整后续写交互测试时也有稳定的参数可读。反过来跳过声明直接写 Story得到的是一个空面板和一堆事后补的手写 argTypes。跨框架团队可以更进一步把docgen 输出面板里不缺属性设为组件合入前的检查项——面板少一个属性这个 PR 就不算完。创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进