返回博客

在 Storybook 中构建页面

为难以到达的页面状态编写故事

loading
Kyle Gach
@kylegach
最后更新

在一个应用中构建页面起初可能看起来很简单,但随着项目成熟,事情会变得更加复杂。如果网络失败或数据丢失会发生什么?更糟糕的是,你的应用获取到格式错误或不完整的数据。在所有这些情况下,页面应该如何渲染?

Mozilla、The Guardian 和 Shopify 的领先团队使用 Storybook 来捕获难以重现的页面状态。这有助于他们有条不紊地解决用户可能遇到的每种情况。

本文展示了如何在 Storybook 中隔离开发页面。我们将使用组件百科全书——一个全新的网站,它收录了世界各地的 UI 组件,供前端开发人员参考——来说明这个过程。它由数百个页面组成,具有广泛的 UI 状态和数据差异需要考虑。

Three examples of the Project Detail page, for Adobe Spectrum Design System, Monday.com Vibe Design System, and The Guardian Web
每个页面都根据可用数据进行自定义

为什么将 Storybook 用于页面?

页面具有非显而易见的要求,例如布局、可访问性、设备兼容性、性能和用户个性化。这为前端开发人员带来了无数的状态来构建和维护。

Storybook 帮助你隔离构建每个页面状态,然后将其保存为故事,以便在 QA 和自动化测试期间重新访问。

💎 捕获边缘情况
故事演示了页面的各种状态。其中包括在你的应用中难以到达的边缘情况,例如加载和空状态。

🖼 分享你的工作
通过发布你的 Storybook,你可以与你的团队共享给定状态下特定故事的链接以征求反馈。这简化了签核流程。

✅ 测试用户交互
即使是最基本的任务也需要用户完成页面上多个组件的一系列步骤。你可以通过编写用户行为脚本并在 play 函数中编写断言来验证此类交互。

如何在 Storybook 中构建页面

页面实际上只是一个具有额外数据要求的组件。你以与常规组件类似的方式构建它。首先,在最常见的“默认”状态下开发页面,所有数据都存在。然后为边缘情况编写故事,例如无数据、数据丢失、响应式断点等。

故事帮助你跟踪页面状态

页面的理想状态是提供所有数据时。我们可以编写一个 Default 故事,其中包含捕获此状态的输入

Default.args = {
 authorAvatarUrl: mockImageUrl(50, 50),
 componentCount: 55,
 components: mockComponents,
 contributors: [
   {
     avatarUrl: mockImageUrl(50, 50),
     name: 'First Last',
   },
   {
     avatarUrl: mockImageUrl(50, 50),
     name: 'First Last',
   },
   {
     avatarUrl: mockImageUrl(50, 50),
     name: 'First Last',
   },
 ],
 description: 'Spectrum provides components and tools to help product teams work more efficiently, and to make Adobes applications more cohesive',
 downloads: 15123,
 gitHubUrl: '#',
 org: 'Adobe',
 packageName: 'packagename',
 storyCount: 135,
 storybookUrl: '#',
 title: 'Spectrum Design System',
}
The Project Detail page for Adobe Spectrum Design System, in its ideal state, rendered as a story in Storybook

但是,如果遇到不太理想的情况,例如“无数据”状态呢?我们可以重用来自 Default 故事的输入,然后覆盖一些值以正确创建该状态

NoComponents.args = {
 ...Default.args,
 componentCount: 0,
 components: []
}
The Project Detail page in a story for the "no components" state

有时,页面的状态需要通过交互来演示,而不是通过提供输入。我们可以使用play 函数来模拟交互,例如在过滤器控件中键入内容以检查其行为和结果

Filter.args = {
 ...Default.args
};
Filter.play = async ({ canvasElement }) => {
 const canvas = within(canvasElement);
 const filter = await canvas.findByLabelText('Filter by name');
 
 await userEvent.type(filter, 'But', { delay: 100 });
};
An animation of a story demonstrating the "components filter" functionality
使用交互测试模拟用户行为

将复杂页面分解为简单组件

如果你采用组件驱动的方法,其中 UI 由可重用组件组装而成,则可以通过将其分解为组成组件来进一步分解页面。

例如,组件百科全书中的 Project 页面将其大部分复杂性都放在标题区域中。为了将页面级关注点(如数据加载)与组件级关注点(如标题长度)分开,我们将标题提取到其自己的组件中,并带有自己的故事。

Illustration of extracting the header component out of the rest of the page, with text reading "Decompose complex parts of a page into their own component"

使用插件来测试行为、可访问性及更多内容

编写完故事后,我们可以使用插件使我们的 Storybook 更加有用。除了演示页面的各种状态外,我们还可以使用a11y 插件检查可访问性,该插件为我们提供了一个方便的检查状态面板,该面板会在我们工作时更新。更进一步,我们可以在 CI 中使用新发布的交互测试将我们的故事作为自动化测试运行。

结论

构建页面是所有开发人员都必须做的事情。在应用中构建页面是困难且容易出错的,因为许多状态难以重现。你最终会点击用户流程或修改 fixtures 来处理每个状态。

故事是页面“已知良好状态”的实时文档,你可以与你的团队共享。你隔离开发每个页面的故事。这使你可以避免复杂的业务逻辑或混乱的应用上下文。

本文的灵感来自于我们为构建组件百科全书页面所做的努力,该百科全书收集了包含组件和页面的公共 Storybook,供浏览和学习。在下面注册 Storybook 邮件列表,以获取组件百科全书的更新和抢先体验。或者在此处提交你自己的 Storybook 的 URL

加入 Storybook 邮件列表

获取最新的新闻、更新和发布

6,730位开发人员及更多

我们正在招聘!

加入 Storybook 和 Chromatic 背后的团队。构建被成千上万的开发人员在生产环境中使用的工具。远程优先。

查看职位

热门帖子

Storybook 如何帮助设计师和开发人员保持同步

将组件连接到设计规范、文档和反馈
loading
Varun Vachhar

社区案例展示 #1

Figma、SWC、Tensorflow、Spotify 播放列表等等
loading
Dominic Nguyen

使用 Storybook 进行交互测试

你编写故事,Storybook 运行测试
loading
Michael Shilman
加入社区
6,730位开发人员及更多
为什么为什么选择 Storybook组件驱动的 UI
文档指南教程更新日志遥测
社区插件参与其中博客
案例展示探索项目组件词汇表
开源软件
Storybook - Storybook 中文

特别感谢 Netlify CircleCI