命名组件和层级结构
观看视频教程
Storybook 提供了一种强大的方式来组织您的 Story,为您提供必要的工具,以便根据您的组织需求和偏好对 Story 进行分类、搜索和过滤。
结构和层级结构
在组织 Storybook 时,有两种结构化 Story 的方法:**隐式**和**显式**。**隐式方法**依赖 Story 的物理位置来在侧边栏中定位它们,而**显式方法**则利用 title
参数来放置 Story。
根据您组织 Storybook 的方式,您可以看到 Story 层级结构由多个部分组成
- **类别**:由 Storybook 生成的 Story 和文档页面的顶层分组
- **文件夹**:用于在侧边栏中对组件和 Story 进行分组的中层组织单元,代表应用程序的某个功能或部分
- **组件**:代表 Story 正在测试的组件的底层组织单元
- **文档**:组件的自动生成的**文档页面**
- **Story**:测试特定组件状态的单个 Story
命名 Story
创建 Story 时,您可以显式使用 title
参数来定义 Story 在侧边栏中的位置。它还可以用于在可展开的界面中将相关组件**分组**在一起,以帮助 Storybook 的组织,为用户提供更直观的体验。例如
// 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 = {
/* 👇 The title prop is optional.
* See https://storybook.org.cn/docs/configure/#configure-story-loading
* to learn how to generate automatic titles
*/
title: 'Button',
component: Button,
} satisfies Meta<typeof Button>;
export default meta;
效果如下
分组
也可以在可展开的界面中对相关组件进行分组,以帮助 Storybook 的组织。为此,请使用 /
作为分隔符
// 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 = {
/* 👇 The title prop is optional.
* See https://storybook.org.cn/docs/configure/#configure-story-loading
* to learn how to generate automatic titles
*/
title: 'Design System/Atoms/Button',
component: Button,
} satisfies Meta<typeof Button>;
export default meta;
// 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 { CheckBox } from './Checkbox';
const meta = {
/* 👇 The title prop is optional.
* See https://storybook.org.cn/docs/configure/#configure-story-loading
* to learn how to generate automatic titles
*/
title: 'Design System/Atoms/Checkbox',
component: CheckBox,
} satisfies Meta<typeof CheckBox>;
export default meta;
效果如下
根层级
默认情况下,顶级分组在 Storybook UI 中显示为“根层级”(即,大写、不可展开的项目)。如果需要,您可以**配置 Storybook**并禁用此行为。如果您需要为用户提供精简的体验,这很有用;但是,如果您的 Storybook 包含大量组件 Story,我们建议根据文件层级结构命名您的组件。
单 Story 提升
单 Story 组件(即,没有**同级**的组件 Story),其**显示名称**与组件名称(title
的最后一部分)完全匹配时,会自动提升以替换 UI 中的父组件。例如
// Replace your-framework with the framework you are using, e.g. react-vite, nextjs, vue3-vite, etc.
import type { Meta, StoryObj } from '@storybook/your-framework';
import { Button as ButtonComponent } from './Button';
const meta = {
/* 👇 The title prop is optional.
* See https://storybook.org.cn/docs/configure/#configure-story-loading
* to learn how to generate automatic titles
*/
title: 'Design System/Atoms/Button',
component: ButtonComponent,
} satisfies Meta<typeof ButtonComponent>;
export default meta;
type Story = StoryObj<typeof meta>;
// This is the only named export in the file, and it matches the component name
export const Button: Story = {};
由于 Story 导出会自动进行“首字母大写”(myStory
变为 "My Story"
),您的组件名称应该与此匹配。或者,您可以使用 myStory.storyName = '...'
来覆盖 Story 名称以匹配组件名称。
排序 Story
默认情况下,Storybook 根据导入顺序对 Story 进行排序。但是,您可以通过在 preview.js
文件中的 options
参数中添加 storySort
来自定义此模式,以满足您的需求并提供更直观的体验。
// Replace your-framework with the framework you are using, e.g. react-vite, nextjs, vue3-vite, etc.
import type { Preview } from '@storybook/your-framework';
const preview: Preview = {
parameters: {
options: {
// The `a` and `b` arguments in this function have a type of `import('storybook/internal/types').IndexEntry`. Remember that the function is executed in a JavaScript environment, so use JSDoc for IntelliSense to introspect it.
storySort: (a, b) =>
a.id === b.id ? 0 : a.id.localeCompare(b.id, undefined, { numeric: true }),
},
},
};
export default preview;
除了唯一的 Story 标识符外,您还可以使用 title
、name
和导入路径来使用 storySort
函数对 Story 进行排序。
storySort
还可以接受一个配置对象。
// Replace your-framework with the framework you are using, e.g. react-vite, nextjs, vue3-vite, etc.
import type { Preview } from '@storybook/your-framework';
const preview: Preview = {
parameters: {
options: {
storySort: {
method: '',
order: [],
locales: '',
},
},
},
};
export default preview;
字段 | 类型 | 描述 | 必需 | 默认值 | 示例 |
---|---|---|---|---|---|
method | 字符串 | 告诉 Storybook 如何显示 Story 的顺序 | 否 | Storybook configuration | 'alphabetical' |
order | 数组 | 按提供的名称排序要显示的 Story | 否 | 空数组 [] | ['Intro', 'Components'] |
includeNames | 布尔值 | 在排序计算中包含 Story 名称 | 否 | 否 | 是 |
locales | 字符串 | 需要显示的区域设置 | 否 | 系统区域设置 | en-US |
要按字母顺序排序 Story,将 method
设置为 'alphabetical'
,并可选地设置 locales
字符串。要使用自定义列表排序 Story,请使用 order
数组;不与 order
列表中的项目匹配的 Story 将出现在列表中的项目之后。
order
数组可以接受一个嵌套数组来对二级 Story 类型进行排序。例如
// Replace your-framework with the framework you are using, e.g. react-vite, nextjs, vue3-vite, etc.
import type { Preview } from '@storybook/your-framework';
const preview: Preview = {
parameters: {
options: {
storySort: {
order: ['Intro', 'Pages', ['Home', 'Login', 'Admin'], 'Components'],
},
},
},
};
export default preview;
这将导致 Story 排序如下
Intro
,然后是Intro/*
StoryPages
StoryPages/Home
和Pages/Home/*
StoryPages/Login
和Pages/Login/*
StoryPages/Admin
和Pages/Admin/*
StoryPages/*
StoryComponents
和Components/*
Story- 所有其他 Story
如果您想将特定类别排序到列表末尾,可以在您的 order
数组中插入一个 *
来指示“所有其他 Story”应该放置的位置
// Replace your-framework with the framework you are using, e.g. react-vite, nextjs, vue3-vite, etc.
import type { Preview } from '@storybook/your-framework';
const preview: Preview = {
parameters: {
options: {
storySort: {
order: ['Intro', 'Pages', ['Home', 'Login', 'Admin'], 'Components', '*', 'WIP'],
},
},
},
};
export default preview;
在此示例中,WIP
类别将显示在列表末尾。
请注意,order
选项独立于 method
选项;Story 首先按 order
数组排序,然后按 method: 'alphabetical'
或默认的 configure()
导入顺序排序。