观看视频教程
故事捕获 UI 组件的渲染状态。它是一个带有注释的对象,描述了组件在给定一组参数的情况下,其行为和外观。
Storybook 在谈论 React 的 props
、Vue 的 props
、Angular 的 @Input
和其他类似概念时,使用通用术语参数 (简称 args)。
组件的故事定义在一个故事文件中,该文件与组件文件并存。故事文件仅用于开发,不会包含在生产包中。在您的文件系统中,它看起来像这样
components/
├─ Button/
│ ├─ Button.js | ts | jsx | tsx | vue | svelte
│ ├─ Button.stories.js | ts | jsx | tsx
我们根据 组件故事格式 (CSF) 定义故事,这是一个基于 ES6 模块的标准,易于编写且可在工具之间移植。
关键要素是 默认导出,它描述了组件,以及 命名导出,它描述了故事。
默认 导出元数据控制 Storybook 如何列出您的故事,并提供插件使用的信息。例如,以下是故事文件 Button.stories.js|ts
的默认导出
ℹ️从 Storybook 版本 7.0 开始,故事标题将在构建过程的静态分析中进行分析。默认 导出必须包含一个 title
属性,该属性可以静态读取,或者一个 component
属性,可以从中计算出自动标题。使用 id
属性来自定义故事 URL 也必须静态可读。
使用 CSF 文件的命名导出定义您的组件的故事。我们建议您对故事导出使用 UpperCamelCase。以下是如何在“primary”状态下渲染 Button
并导出名为 Primary
的故事。
React Hooks 是方便的辅助方法,用于使用更简化的方式创建组件。如果您需要它们,您可以在创建组件的故事时使用它们,尽管您应该将它们视为高级用例。我们建议在编写自己的故事时尽可能地使用 args。例如,以下是一个使用 React Hooks 更改按钮状态的故事
您可以重命名任何您需要的特定故事。例如,为了给它一个更准确的名称。以下是如何更改 Primary
故事的名称
您的故事现在将与给定的文本一起显示在侧边栏中。
故事是一个描述如何渲染组件的对象。您每个组件可以有多个故事,这些故事可以互相构建。例如,我们可以根据上面的主要故事添加辅助和三级故事。
更重要的是,您可以导入args
以在为其他组件编写故事时重复使用,这在您构建复合组件时非常有用。例如,如果我们制作一个ButtonGroup
故事,我们可能会从其子组件Button
中混搭两个故事。
ButtonGroup.stories.ts|tsx
当 Button 的签名更改时,您只需要更改 Button 的故事以反映新的模式,ButtonGroup 的故事将自动更新。这种模式允许您在整个组件层次结构中重复使用数据定义,从而使您的故事更易于维护。
但这还不是全部!故事函数中的每个参数都可以使用 Storybook 的Controls 面板实时编辑。这意味着您的团队可以动态地在 Storybook 中更改组件以进行压力测试并查找边缘情况。
您还可以使用 Controls 面板在调整控制值后编辑或保存新故事。
加载项可以增强参数。例如,Actions 自动检测哪些参数是回调,并向它们附加一个日志记录函数。这样,交互(例如点击)就会记录在操作面板中。
Storybook 的play
函数和@storybook/addon-interactions
是方便的辅助方法,用于测试否则需要用户干预的组件场景。它们是小的代码片段,在您的故事渲染后执行一次。例如,假设您想验证一个表单组件,您可以使用play
函数编写以下故事,以检查组件在使用信息填充输入时如何响应。
如果没有play
函数和@storybook/addon-interactions
的帮助,您必须编写自己的故事并手动与组件进行交互以测试所有可能的用例场景。
参数是 Storybook 定义故事静态元数据的方法。故事的参数可用于为故事或故事组的各个加载项提供配置。
例如,假设您想针对与应用程序中其他组件不同的背景集测试 Button 组件。您可以添加一个组件级backgrounds
参数。
此参数将指示背景加载项在选择 Button 故事时重新配置自身。大多数加载项都是通过基于参数的 API 配置的,并且可以在全局、组件 和故事 级进行影响。
装饰器是一种机制,可以在渲染故事时将组件包装在任意标记中。组件通常是使用对“渲染位置”的假设创建的。您的样式可能需要主题或布局包装器,或者您的 UI 可能需要特定的上下文或数据提供者。
一个简单的例子是在组件的故事中添加填充。使用一个装饰器来完成此操作,该装饰器将故事包装在一个带有填充的div
中,如下所示。
装饰器可能更加复杂,并且通常由加载项 提供。您也可以在故事、组件 和全局 级配置装饰器。
有时您可能有两个或多个组件创建为一起工作。例如,如果您有一个父List
组件,它可能需要子ListItem
组件。
在这种情况下,为每个故事渲染不同的函数是有意义的。
您还可以在List
组件中重复使用子ListItem
的故事数据。这更容易维护,因为您不必在多个地方更新它。
💡请注意,以这种方式编写故事有缺点,因为在构建更复杂的复合组件时,您无法充分利用参数机制和组合参数。有关更多讨论,请参见多组件故事 工作流文档。