ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

Storybook Docs 页面 Controls 文档块配置指南:用 `parameters.docs.controls` 参数精确控制 Args 控制表格

2026/9/8 21:18:05 拓冰建站 浏览量
Storybook Docs 页面 Controls 文档块配置指南:用 `parameters.docs.controls` 参数精确控制 Args 控制表格 Storybook Docs 页面 Controls 文档块配置指南用parameters.docs.controls参数精确控制 Args 控制表格【免费下载链接】storybookStorybook is the industry standard workshop for building, documenting, and testing UI components in isolation项目地址: https://gitcode.com/GitHub_Trending/st/storybook本文围绕 Storybook addon-docs 中Controls文档块在 Docs 页面下的配置方式展开核心讲解其exclude/include/sort/of等属性与parameters.docs.controls参数之间的默认值来源关系。你将掌握如何在不改动 MDX 的前提下通过 componentmeta级、story 级与全局级参数统一控制参数表格的显示内容并了解底层过滤filterArgTypes的精确匹配语义从而在不同框架React、Angular、Vue、Svelte、Web Components与 CSF 3 / CSF Next 两种写法之间灵活落地。一、先厘清概念Controls 文档块与 Controls 面板并不是一回事Controls是 Storybook 的 Doc Blocks API 之一用于在 Docs 页面中为指定 story 展示一张动态的 Args 参数表格它既用来文档化组件的 props 接口也可以联动修改同页中由Story或Canvas文档块单独渲染的 story 的实时参数值。这里需要特别区分的边界是本文讨论的parameters.docs.controls只配置Docs 页面里使用的Controls块由storybook/addon-docs/blocks导出侧边栏的Controls 面板Addon Controls需要看 essentials/controls 特性文档 进行配置二者不是同一个 API若只需控制单个 arg的控件形态输入框、下拉、颜色选择器等则应到 argTypes 的 control 配置 中为每个 arg 单独指定。此外如果只是想要一张不含交互控件的静态参数表格应改用ArgTypes文档块 而不是Controls。二、核心机制MDX 属性与参数的默认值关系与大部分文档块一致Controls既可以通过 MDX 上的 props 配置也可以在其所属命名空间parameters.docs.controls里配置参数——MDX props 的默认值正来自于对应参数。源码层面Controls.tsx 的getControlsFilterProps很直白地表达了这一取值逻辑function getControlsFilterProps(story: PreparedStory, props: ControlsProps): ControlsParameters { const controlsParameters story.parameters.docs?.controls || ({} as ControlsParameters); return { include: props.include ?? controlsParameters.include, exclude: props.exclude ?? controlsParameters.exclude, sort: props.sort ?? controlsParameters.sort, }; }即显式传入的 MDX 属性优先未传入时才回退读取story.parameters.docs.controls中的同名配置。因此下面两段配置在效果上完全等价在.stories文件的 component/meta 级参数中声明docs.controls.exclude见本文第四节在 MDX 中通过属性声明Controls exclude{[style]} /见本文第六节。三、参数结构总览parameters.docs.controls下可配置的键与Controls块 props 一一对应参数 / 属性类型默认值作用excludestring[] \| RegExpparameters.docs.controls.exclude从参数表格中排除指定控件名称命中数组元素或匹配正则的控件将被剔除includestring[] \| RegExpparameters.docs.controls.include仅保留指定控件名称不命中数组或正则的控件全部被剔除sortnone \| alpha \| requiredFirstparameters.docs.controls.sort或none控制参数表格的排序方式ofStory 导出或 CSF 文件导出—指定从哪个 story 读取控件若传入整个 CSF 导出对象则取文件中的 primary第一个storyControlsParameters类型定义也能在 Controls.tsx 顶部 找到type ControlsParameters { include?: PropDescriptor; exclude?: PropDescriptor; sort?: SortType; }; type ControlsProps ControlsParameters { of?: Renderer[component] | ModuleExports; };其中sort三种取值的语义是none不排序按控件被处理的原始顺序展示alpha按 argType 名称字母序排序requiredFirst与alpha相同但必填控件排在前面。四、在 componentmeta级配置exclude多框架完整示例官方推荐最常见的使用位置是 story 文件的 meta 定义处component 参数层级。下面按框架与 CSF 书写风格完整给出与文档块组件级配置等价的参数化写法。AngularCSF 3import type { Meta } from storybook/angular; import { Button } from ./button.component; const meta: MetaButton { component: Button, parameters: { docs: { controls: { exclude: [style] }, }, }, }; export default meta;React / Vue 等通用渲染器CSF 3satisfies写法// Replace your-framework with the framework you are using, e.g. react-vite, nextjs, vue3-vite, etc. import type { Meta } from storybook/your-framework; import { Button } from ./Button; const meta { component: Button, parameters: { docs: { controls: { exclude: [style] }, }, }, } satisfies Metatypeof Button; export default meta;对应的 JavaScript 版本import { Button } from ./Button; export default { component: Button, parameters: { docs: { controls: { exclude: [style] }, }, }, };SvelteSvelte CSF 的defineMeta写法script module import { defineMeta } from storybook/addon-svelte-csf; import Button from ./Button.svelte; const { Story } defineMeta({ component: Button, parameters: { docs: { controls: { exclude: [style] }, }, }, }); /scriptTypeScript 版本的 Svelte CSFscript module import { defineMeta } from storybook/addon-svelte-csf; import Button from ./Button.svelte; const { Story } defineMeta({ component: Button, parameters: { docs: { controls: { exclude: [style] }, }, }, }); /script传统 Svelte CSF 3export default也支持同样写法import Button from ./Button.svelte; export default { component: Button, parameters: { docs: { controls: { exclude: [style] }, }, }, };TypeScript 版将your-framework替换为svelte-vite或sveltekit// Replace your-framework with svelte-vite or sveltekit import type { Meta } from storybook/your-framework; import Button from ./Button.svelte; const meta { component: Button, parameters: { docs: { controls: { exclude: [style] }, }, }, } satisfies Metatypeof Button; export default meta;Web Components通过自定义元素名引用组件export default { title: Button, component: demo-button, parameters: { docs: { controls: { exclude: [style] }, }, }, };import type { Meta } from storybook/web-components-vite; const meta: Meta { title: Button, component: demo-button, parameters: { docs: { controls: { exclude: [style] }, }, }, }; export default meta;注意Web Components 的 CSF 中没有导入组件类而是把自定义元素标签名如demo-button通过titlecomponent传入参数化排除控件的写法保持一致。五、CSF Next实验性中的等价写法Storybook 正在推进的 CSF Next 实验语法中story 的元数据统一由preview.meta({ ... })包裹声明parameters.docs.controls的写法随之迁移。以下是各框架的等价示例。ReactCSF Next import preview from ../.storybook/preview; import { Button } from ./Button; const meta preview.meta({ component: Button, parameters: { docs: { controls: { exclude: [style] }, }, }, });import preview from ../.storybook/preview; import { Button } from ./Button; const meta preview.meta({ component: Button, parameters: { docs: { controls: { exclude: [style] }, }, }, });VueCSF Next import preview from ../.storybook/preview; import Button from ./Button.vue; const meta preview.meta({ component: Button, parameters: { docs: { controls: { exclude: [style] }, }, }, });import preview from ../.storybook/preview; import Button from ./Button.vue; const meta preview.meta({ component: Button, parameters: { docs: { controls: { exclude: [style] }, }, }, });AngularCSF Next import preview from ../.storybook/preview; import { Button } from ./button.component; const meta preview.meta({ component: Button, parameters: { docs: { controls: { exclude: [style] }, }, }, });Web ComponentsCSF Next import preview from ../.storybook/preview; const meta preview.meta({ title: Button, component: demo-button, parameters: { docs: { controls: { exclude: [style] }, }, }, });import preview from ../.storybook/preview; const meta preview.meta({ title: Button, component: demo-button, parameters: { docs: { controls: { exclude: [style] }, }, }, });在 Svelte 生态中CSF Next 形态与defineMetaSvelte CSF殊途同归——只需把参数放进defineMeta({ ... })的配置对象即可写法同上一节。可以看出无论语法如何演进参数名与嵌套结构始终不变迁移成本集中在语法外壳而非配置模型本身。六、与 MDX 属性写法等价Controls exclude{...} /下面的 MDX 在文档页中与上述所有参数化写法效果完全相同Controls of{ButtonStories} exclude{[style]} /典型用法是先在同一 Docs 页中渲染一个Canvas of{ButtonStories.Primary}紧跟其后的Controls of{ButtonStories.Primary} /展示可交互参数表格。若省略ofControls将读取当前文档上下文中的 primary storyControls.tsx 中通过usePrimaryStory()获得。七、匹配与过滤的底层实现不论走参数还是属性最终都会进入 core 的filterArgTypes工具函数完成行过滤。核心实现见 filterArgTypes.tsexport const filterArgTypes ( argTypes: StrictArgTypes, include?: PropDescriptor, exclude?: PropDescriptor ) { if (!include !exclude) { return argTypes; } return ( argTypes pickBy(argTypes, (argType, key) { const name argType.name || key.toString(); return !!(!include || matches(name, include)) (!exclude || !matches(name, exclude)); }) ); };PropDescriptor的定义与匹配判定在文件开头filterArgTypes.tsexport type PropDescriptor string[] | RegExp; const matches (name: string, descriptor: PropDescriptor) Array.isArray(descriptor) ? descriptor.includes(name) : name.match(descriptor);从中可以提取几条对实际使用有直接指导意义的语义数组按精确全名匹配传入string[]时是descriptor.includes(name)控件名必须与数组元素完全相等才会被命中不存在前缀/子串匹配正则按RegExp.test匹配传入RegExp时执行name.match(descriptor)可用/^on[A-Z]/这类模式批量筛选。文档中称按名称匹配正则的控件会被排除/包含指的就是该分支include与exclude同时作用判定为(!include || matches(name, include)) (!exclude || !matches(name, exclude))即先要求满足 include若指定再要求不落入 exclude若指定匹配目标是 argType 的 name判定时优先取argType.name未显式给出 name 时才回退到 argType 的 key因此你在 meta/story 层为 arg 取的argTypeskey 也会生效。当某个 doc block 同时存在主组件与subcomponents时Controls 会把主组件与每个子组件拆分为页签Tabbed ArgsTableinclude/exclude过滤会对每个页签的 rows 独立执行一遍见 Controls.tsx。八、其他作用域project全局与 story单个层级参数可以在三处作用域注入Storybook 会按 story component project 的优先级向上查找component 级写在.stories文件的 meta 对象中本文第四节对整组 stories 生效story 级写在单个 story 导出的parameters中只影响该 story 文档块project全局级写在 .storybook/preview 配置 中对全部 stories 生效。全局级示例storybook-preview-doc-blocks-controls-exclude-prop 展示了完整的框架对照写法export default { parameters: { docs: { controls: { exclude: [style] }, }, }, };若在 CSF Next 项目中使用全局配置则通过definePreviewaddonDocs()注入// Replace your-framework with the framework you are using (e.g., react-vite, nextjs, nextjs-vite) import { definePreview } from storybook/your-framework; import addonDocs from storybook/addon-docs; export default definePreview({ addons: [addonDocs()], parameters: { docs: { controls: { exclude: [style] }, }, }, });九、include / sort 参数同样可参数化exclude之外其余参数也都可放进parameters.docs.controls。仓库自带的演示 storiesControlsParameters.stories.tsx直观展示了三种典型参数化场景export const Include: Story { ...NoParameters, parameters: { docs: { controls: { include: [a] } } }, }; export const Exclude: Story { ...NoParameters, parameters: { docs: { controls: { exclude: [a] } } }, }; export const Sort: Story { ...NoParameters, parameters: { docs: { controls: { sort: alpha } } }, };include只保留指定控件include是exclude的镜像操作只展示名字命中数组精确命中或正则匹配的控件其余一律隐藏。它适用于只想高亮少数核心 props、把其余参数收敛的场景。sort控制展示顺序默认值与 MDX 文档一致缺省时取parameters.docs.controls.sort若都未配置则回退为noneControls.tsx控件按原有处理顺序排列。需要稳定可预期的排列时可配置为alpha需要把必填项置顶时可配置为requiredFirst。十、实战建议与易错点要排除的控件名是 argType 的 name/key你写的exclude: [style]针对的是参数表中控件的名字而不是 CSS 样式属性或其他字段不要在参数中重复声明 MDX 已有属性属性优先级高于参数若二者同时配置MDX 中的显式值会胜出。当需要全项目统一例如始终隐藏继承来的style优先把规则放进.storybook/preview当只需要在某一份 CSF 中收口则写在 meta 级即可注意与单个控件配置的边界parameters.docs.controls不控制控件类型。想要改变某个 arg 用文本输入还是下拉选择请通过 argTypes 的 control 字段 单独声明同理若Controls表格中没出现预期控件还应检查是否在.storybook/preview中开启了inline选项——Docs 页的 Controls 只有在未关闭 inline story 时才有可用的交互控件测试与示例验证addon-docs 自带的 Controls 交互 storyControls.stories.tsx与上面的ControlsParameters系列是观察参数行为的快速参照在 Docs 里调试排布时可打开对应 story 的文档页直接切换exclude、include、sort观察表格变化。十一、小结parameters.docs.controls是 Docs 文档块体系为Controls组件预留的标准配置通道exclude/include用数组或正则收敛参数表格的行集sort决定行的排序策略且它们天然成为 MDXControls /对应属性的默认值来源。由于取值合并逻辑位于块组件内部属性优先、参数兜底你完全可以在 project 级定默认、在 meta 级按组件收口、在单个 story 级做特例从而在不同规模的项目里形成一致的文档策略。【免费下载链接】storybookStorybook is the industry standard workshop for building, documenting, and testing UI components in isolation项目地址: https://gitcode.com/GitHub_Trending/st/storybook创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考