Args
观看视频教程
故事是具有一组参数的组件,这些参数定义了组件应如何渲染。“Args”是 Storybook 中用于在单个 JavaScript 对象中定义这些参数的机制。Args 可用于动态更改 props、slots、样式、输入等。它允许 Storybook 及其插件实时编辑组件。您无需修改底层组件代码即可使用 args。
当 arg 的值发生变化时,组件会重新渲染,允许您通过影响 args 的插件在 Storybook 的 UI 中与组件进行交互。
了解如何以及为何在介绍中编写故事。有关 args 如何工作的详细信息,请继续阅读。
Args 对象
args
对象可以在故事、组件和全局级别定义。它是一个 JSON 可序列化对象,由字符串键和匹配的有效值类型组成,这些值可以传递给您的框架组件。
故事 Args
要定义单个故事的 args,请使用 args
CSF 故事键
// Replace your-framework with the framework you are using, e.g. react-vite, nextjs, nextjs-vite, etc.
import type { Meta, StoryObj } from '@storybook/your-framework';
import { Button } from './Button';
const meta = {
component: Button,
} satisfies Meta<typeof Button>;
export default meta;
type Story = StoryObj<typeof meta>;
export const Primary: Story = {
args: {
primary: true,
label: 'Button',
},
};
这些 args 只适用于它们所附加的故事,尽管您可以通过 JavaScript 对象复用复用它们
// Replace your-framework with the name of your framework
import type { Meta, StoryObj } from '@storybook/your-framework';
import { Button } from './Button';
const meta = {
component: Button,
} satisfies Meta<typeof Button>;
export default meta;
type Story = StoryObj<typeof meta>;
export const Primary: Story = {
args: {
primary: true,
label: 'Button',
},
};
export const PrimaryLongName: Story = {
args: {
...Primary.args,
label: 'Primary with a really long name',
},
};
在上面的示例中,我们使用了 ES 2015 的对象展开特性。
组件 Args
您也可以在组件级别定义 args;它们将应用于该组件的所有故事,除非您覆盖它们。为此,请在 default
CSF 导出上使用 args
键
// Replace your-framework with the framework you are using, e.g. react-vite, nextjs, nextjs-vite, etc.
import type { Meta } from '@storybook/your-framework';
import { Button } from './Button';
const meta = {
component: Button,
//👇 Creates specific argTypes
argTypes: {
backgroundColor: { control: 'color' },
},
args: {
//👇 Now all Button stories will be primary.
primary: true,
},
} satisfies Meta<typeof Button>;
export default meta;
全局 Args
您也可以在全局级别定义 args;它们将应用于每个组件的故事,除非您覆盖它们。为此,请在 preview.js|ts
的默认导出中定义 args
属性
// 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 = {
// The default value of the theme arg for all stories
args: { theme: 'light' },
};
export default preview;
对于大多数全局 args 的使用场景,全局变量 (globals) 是定义全局应用设置(如主题)的更好工具。使用全局变量可以让用户通过工具栏菜单更改值。
Args 组合
您可以将故事的参数分离出来,以便在其他故事中组合使用。以下是如何将同一组件的多个故事的 args 组合起来的方法。
// Replace your-framework with the name of your framework
import type { Meta, StoryObj } from '@storybook/your-framework';
import { Button } from './Button';
const meta = {
component: Button,
} satisfies Meta<typeof Button>;
export default meta;
type Story = StoryObj<typeof meta>;
export const Primary: Story = {
args: {
primary: true,
label: 'Button',
},
};
export const Secondary: Story = {
args: {
...Primary.args,
primary: false,
},
};
如果您发现对组件的大多数故事都重复使用相同的 args,则应考虑使用组件级 args。
在为由其他组件组合而成的复合组件编写故事时,Args 非常有用。复合组件通常会将其参数原封不动地传递给子组件,同样,它们的的故事也可以是其子组件故事的组合。通过 args,您可以直接组合参数
// Replace your-framework with the framework you are using, e.g. react-vite, nextjs, nextjs-vite, etc.
import type { Meta, StoryObj } from '@storybook/your-framework';
import { Page } from './Page';
//👇 Imports all Header stories
import * as HeaderStories from './Header.stories';
const meta = {
component: Page,
} satisfies Meta<typeof Page>;
export default meta;
type Story = StoryObj<typeof meta>;
export const LoggedIn: Story = {
args: {
...HeaderStories.LoggedIn.args,
},
};
Args 可以修改组件的任何方面
您可以在故事中使用 args 来配置组件的外观,类似于您在应用程序中的做法。例如,以下是如何使用 footer
arg 来填充子组件的方法
// Replace your-framework with the framework you are using, e.g. react-vite, nextjs, nextjs-vite, etc.
import type { Meta, StoryObj } from '@storybook/your-framework';
import { Page } from './Page';
type PagePropsAndCustomArgs = React.ComponentProps<typeof Page> & { footer?: string };
const meta = {
component: Page,
render: ({ footer, ...args }) => (
<Page {...args}>
<footer>{footer}</footer>
</Page>
),
} satisfies Meta<PagePropsAndCustomArgs>;
export default meta;
type Story = StoryObj<typeof meta>;
export const CustomFooter = {
args: {
footer: 'Built with Storybook',
},
} satisfies Story;
通过 URL 设置 args
您还可以通过向 URL 添加 args
查询参数来覆盖当前故事的初始 args 集。通常,您会使用Controls 插件来处理这个问题。例如,以下是如何在 Storybook 的 URL 中设置 size
和 style
args 的方法
?path=/story/avatar--default&args=style:rounded;size:100
作为防止 XSS 攻击的防护措施,URL 中提供的 arg 的键和值仅限于字母数字字符、空格、下划线和破折号。任何其他类型将被忽略并从 URL 中移除,但您仍然可以在 Controls 插件和您的故事中使用它们。
args
参数始终是一组由分号 ;
分隔的 key: value
对。值将被强制转换到其相应的 argTypes
(可能已自动推断)。支持对象和数组。特殊值 null
和 undefined
可以通过前缀感叹号 !
设置。例如,args=obj.key:val;arr[0]:one;arr[1]:two;nil:!null
将被解释为
{
obj: { key: 'val' },
arr: ['one', 'two'],
nil: null
}
类似地,日期和颜色也有特殊的格式。日期对象将被编码为 !date(value)
,其中 value 表示为 ISO 日期字符串。颜色被编码为 !hex(value)
、!rgba(value)
或 !hsla(value)
。请注意,rgb(a) 和 hsl(a) 在 URL 中不应包含空格或百分号。
通过 URL 指定的 Args 将扩展并覆盖在故事上设置的任何默认 args 值。
在故事中设置 args
交互式组件通常需要由其包含组件或页面控制,以响应事件、修改其状态并在 UI 中反映这些变化。例如,当用户切换开关组件时,开关应被选中,并且在 Storybook 中显示的 arg 应反映该变化。要实现这一点,您可以使用 storybook/preview-api
导出的 useArgs
API
// Replace your-framework with the framework you are using, e.g. react-vite, nextjs, nextjs-vite, etc.
import type { Meta, StoryObj } from '@storybook/your-framework';
import { useArgs } from 'storybook/preview-api';
import { Checkbox } from './checkbox';
const meta = {
title: 'Inputs/Checkbox',
component: Checkbox,
} satisfies Meta<typeof Checkbox>;
export default meta;
type Story = StoryObj<typeof Checkbox>;
export const Example = {
args: {
isChecked: false,
label: 'Try Me!',
},
/**
* 👇 To avoid linting issues, it is recommended to use a function with a capitalized name.
* If you are not concerned with linting, you may use an arrow function.
*/
render: function Render(args) {
const [{ isChecked }, updateArgs] = useArgs();
function onChange() {
updateArgs({ isChecked: !isChecked });
}
return <Checkbox {...args} onChange={onChange} isChecked={isChecked} />;
},
} satisfies Story;
映射复杂的 arg 值
复杂的值,如 JSX 元素,无法序列化到管理器(例如 Controls 面板)或与 URL 同步。可以使用 argTypes
中的 mapping
属性将 Arg 值从简单的字符串“映射”到复杂的类型,以规避此限制。它适用于任何 arg,但在与 select
控件类型一起使用时最有意义。
// 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 { Example } from './Example';
const meta = {
component: Example,
argTypes: {
label: {
control: { type: 'select' },
options: ['Normal', 'Bold', 'Italic'],
mapping: {
Bold: <b>Bold</b>,
Italic: <i>Italic</i>,
},
},
},
} satisfies Meta<typeof Example>;
export default meta;
请注意,mapping
不需要穷举所有情况。如果 arg 值不是 mapping
的属性,则直接使用该值。mapping
中的键始终对应于 arg 值,而不是它们在 options
数组中的索引。
在插件中使用 args
如果您正在编写插件,想要读取或更新 args,请使用 storybook/manager-api
导出的 useArgs
hook
import { useArgs } from 'storybook/manager-api';
const [args, updateArgs, resetArgs] = useArgs();
// To update one or more args:
updateArgs({ key: 'value' });
// To reset one (or more) args:
resetArgs((argNames: ['key']));
// To reset all args
resetArgs();