ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

Storybook CSF 2 故事函数写法详解:六大渲染器的渲染描述与 CSF 3 迁移指南

Storybook CSF 2 故事函数写法详解:六大渲染器的渲染描述与 CSF 3 迁移指南 Storybook CSF 2 故事函数写法详解六大渲染器的渲染描述与 CSF 3 迁移指南【免费下载链接】storybookStorybook is the industry standard workshop for building, documenting, and testing UI components in isolation项目地址: https://gitcode.com/GitHub_Trending/st/storybook本篇指南围绕 Storybook 官方 CSFComponent Story Format组件故事格式文档中csf-2-example-story这一示例展开系统讲解CSF 2 时代故事即渲染函数在 Angular、React、Solid、Svelte、Vue 3、Web Components 六个主流渲染器下的标准写法与背后的类型契约并以此为起点梳理向 CSF 3 故事对象迁移的完整路径显式/默认 render、args 继承、自动标题与 codemod。读完你将能读懂并改写仓库中任一套框架的.stories文件并掌握两种 CSF 版本之间的逐行换算方法。背景CSF 故事文件的骨架CSF 是 Storybook 推荐的编写故事方式它是一个基于 ES6 模块、可脱离 Storybook 移植的开放标准。每个故事文件由两部分组成详见 docs/api/csf/index.mdx默认导出default export描述组件元数据核心字段是component必填供 addon 自动生成 prop 表格、展示组件元数据与title可选但需全局唯一决定故事在导航层级中的位置。具名导出named exports文件中的每个具名导出默认代表一个故事。命名导出转换为界面显示名时Storybook 会借助 LodashstartCase与storyNameFromExport处理因此官方推荐具名导出统一以大写字母开头如Primary、Basic并允许通过includeStories/excludeStories把非故事导出mock 数据等排除在侧边栏之外。CSF 2 的故事本质命名导出是渲染函数CSF 2对应 Storybook 6.x 主流写法约定故事就是一个接收args、返回组件实例的函数而args、parameters、decorators等配置则以函数静态属性的形式挂在它身上。这也是迁移到 CSF 3 时最大的心智差异点对象 vs 函数 函数上的注解。下文csf-2-example-story展示的正是故事函数本体的最小形态——为了让读者聚焦渲染写法示例用// Other imports and story implementation隐去了default export、组件 import 与 args 注解带完整默认导出的同系列示例见 docs/_snippets/csf-2-example-starter.md本文末尾会展开对照。ReactJSX 直出 ComponentStory类型// CSF 2 - Button.stories.js|jsx (react) // Other imports and story implementation export const Basic (args) Button {...args} /;// CSF 2 - Button.stories.ts|tsx (react) // Other imports and story implementation export const Basic: ComponentStorytypeof Button (args) Button {...args} /;JS 版本里Basic就是一个把args展开进Button的函数TS 版本则用各 React 系框架react-vite、nextjs、react-webpack5等从storybook/framework导出的ComponentStorytypeof Button标注故事类型让args、argsTypes获得组件 props 的完整类型推导。Solid与 React 同构import 来源不同// CSF 2 - Button.stories.js (solid) // Other imports and story implementation export const Basic (args) Button {...args} /;// CSF 2 - Button.stories.ts|tsx (solid) // Other imports and story implementation export const Basic: ComponentStorytypeof Button (args) Button {...args} /;Solid 的故事函数形态与 React 一致TS 类型的ComponentStory/ComponentMeta需要从 Solid 自身的框架包如storybook-solidjs-vite导入——这一点在完整示例 csf-2-example-starter.md 中体现得很清楚。Angular返回组件配置对象// CSF 2 - Button.stories.ts (angular) // Other imports and story implementation export const Basic: Story (args) ({ props: args, });Angular 的故事函数不再直接写 JSX而是返回一个组件配置描述对象{ props: args }由storybook/angular的Story类型约束。component已在默认导出中声明因此这里只需把args通过props注入到组件实例上。SvelteComponentprops描述对象// CSF 2 - Button.stories.js (svelte) // Other imports and story implementation export const Basic (args) ({ Component: Button, props: args, });// CSF 2 - Button.stories.ts (svelte) // Other imports and story implementation export const Basic: StoryFntypeof Button (args) ({ Component: Button, props: args, });Svelte 渲染器同样接收渲染描述对象用Component指向要渲染的组件、props透传 args。注意其 TS 命名是StoryFntypeof Button从storybook/sveltekit或svelte-vite引入而非 React 系的ComponentStory——这是各渲染器类型导出差异的典型例证。Vue 3setup 模板模板引用// CSF 2 - Button.stories.js (vue) // Other imports and story implementation export const Basic (args) ({ components: { Button }, setup() { return { args }; }, template: Button v-bindargs /, });// CSF 2 - Button.stories.ts (vue) // Other imports and story implementation export const Basic: StoryFntypeof Button (args) ({ components: { Button }, setup() { return { args }; }, template: Button v-bindargs /, });Vue 故事函数返回的是一个运行时组件定义先在components注册组件用setup()把args暴露给模板再以Button v-bindargs /完成 props 绑定。TS 版本同样使用StoryFntypeof Button如来自storybook/vue3-vite。Web Components基于 Lit 的模板函数// CSF 2 - Button.stories.js (web-components) // Other imports and story implementation export const Basic ({ primary, size, label }) htmlcustom-button ?primary${primary} size${size} label${label}/custom-button;// CSF 2 - Button.stories.ts (web-components) // Other imports and story implementation export const Basic: Story ({ primary, backgroundColor, size, label }) htmlcustom-button ?primary${primary} size${size} label${label}/custom-button;Web Components 渲染器依赖lit的html模板标签。这里演示了解构接收args并逐项映射的写法?primary为布尔属性绑定存在即真size、label为普通字符串属性绑定。对比 JS/TS 变体可发现TS 版Story类型约束了参数对象形状并显式解构了四个字段。不同版本间字段不一致TS 多出backgroundColor正说明CSF 2 的函数形参完全由你决定组件在函数体内被如何组装也由你负责。迁移从故事函数到故事对象csf-2-example-story在官方文档中并不是孤立存在的——它位于 docs/api/csf/index.mdx 的 Upgrading from CSF 2 to CSF 3 章节其正文语序是我们先看一个简单的 CSF 2 故事函数……再把它改写成带显式render的故事对象。因此正确理解这段示例的方式是把它作为迁移起点。迁移要素一render 函数外置CSF 3 把命名导出从函数改为对象渲染逻辑放入对象的render字段。上面的Basic函数可以被原样搬进render// CSF 3 - 显式 renderreact 等 JSX 渲染器 // Other imports and story implementation export const Basic { render: (args) Button {...args} /, };// CSF 3 - 显式 rendervue 渲染器TS // Other imports and story implementation export const Basic: Story { render: (args) ({ components: { Button }, setup() { return { args }; }, template: Button v-bindargs /, }), };Svelte / Angular / Web Components 同理只需把原有的渲染函数整体放进render字段完整代码可对照 docs/_snippets/csf-3-example-render.md。换言之CSF 2 的故事函数体就是 CSF 3 中render的天然素材二者是逐字对应的。迁移要素二利用各渲染器的默认 render官方文档同时指出一个关键洞察CSF 2 里大量故事函数是雷同的——取出默认导出声明的组件把 args 展开进去。有趣的不是这个函数本身而是传入的 args见 docs/api/csf/index.mdx。CSF 3 为每个渲染器都内置了默认 render 函数因此最常见的展开 args 渲染组件场景连render都可以省略// CSF 3 - 什么都不用写react // Other imports and story implementation export const Basic {};// CSF 3 - 完整 starterreact, TS import type { Meta, StoryObj } from storybook/your-framework; import { Button } from ./Button; const meta { component: Button, } satisfies Metatypeof Button; export default meta; type Story StoryObjtypeof meta; export const Basic: Story { args: { primary: true } };这正是示例片段标题csf-2-example-story故事函数本身与 csf-3-example-default-render空对象{}之间的鲜明对比一份故事文件里最有价值的信息是 args 与参数语义而非渲染样板。迁移要素三注解继承问题与对象展开CSF 2 中若要基于已有故事派生新故事只能Primary.bind({})// CSF 2 - Button.stories.js|jsx|ts|tsx (common) export const PrimaryOnDark Primary.bind({}); PrimaryOnDark.args Primary.args; PrimaryOnDark.parameters { background: { default: dark } };因为.bind({})只复制函数体不会复制挂在函数上的args、parameters等注解必须手动重新赋值见 csf-2-example-primary-dark-story.md。CSF 3 的故事是普通对象可直接用对象展开无损继承全部注解// CSF 3 - 对象展开携带全部注解 (common) export const PrimaryOnDark { ...Primary, parameters: { background: { default: dark } }, };迁移要素四title 自动生成CSF 2 必须在默认导出中手写层级标题见 csf-2-example-title.md// CSF 2 - Button.stories.js|jsx|ts|tsx (common) export default { title: components/Button, component: Button, };CSF 3 中 title 变为可选项未指定时按磁盘上的文件路径推断见 docs/_snippets/csf-3-example-auto-title.md如需控制排序仍可显式声明。一键迁移codemodStorybook 官方为升级提供 codemod命令入口见 docs/api/csf/index.mdx可在迁移前对存量 CSF 2 文件批量执行转换把函数式命名导出改写为对象式。需要说明的是codemod 处理的是结构迁移渲染差异如是否省略render建议迁移后按上述默认 render原则手工精简。两张对照速查表渲染层对应关系以Basic为例渲染器CSF 2 故事函数CSF 3 迁移结果React / Solid(args) Button {...args} /{ render: (args) Button {...args} / }或省略 render 直接{ args }Angular(args) ({ props: args })render内返回{ props: args }Svelte(args) ({ Component: Button, props: args })render内返回同一描述对象Vue 3(args) ({ components, setup, template })render内返回同一运行时组件定义Web Components({ primary, size, label }) html\...|render 内返回同一 lit 模板配置挂载层对应关系能力CSF 2CSF 3故事形态具名导出为函数具名导出为对象注解挂载函数静态属性Primary.args ...对象字段args: { ... }复用派生Primary.bind({}) 手工重挂注解{ ...Primary }对象展开渲染控制函数体即渲染可选的render字段 / 渲染器默认 render标题默认导出必填title可选可按文件路径自动推断从函数式故事到可组合的故事资产通读本示例及其配套片段后可以总结出贯穿 CSF 演进的一条主线CSF 2 用函数把组件 args 渲染方式耦合在一起故事只能复制、难以组合CSF 3 则把三者解耦为component默认导出、args数据、render可选渲染策略使故事成为可展开、可继承、可被文档与测试工具直接消费的纯数据对象。更深一层的证据在示例的 TS 类型中ComponentStory、StoryFn、Story这些逐渲染器差异化的命名到 CSF 3 时代被统一收敛为Meta/StoryObj参见 csf-3-example-starter.md 中各框架均从各自包导入同一对类型配合satisfies关键字实现组件 props 到 args 的精确类型约束——这也是升级迁移中 TS 报错最集中的区域建议逐文件按先类型后渲染的顺序处理。进一步阅读docs/api/csf/index.mdxCSF 规范全文含命名导出转换规则、name字段、Args、play 函数、自定义 render 与includeStories/excludeStories等完整话题docs/_snippets/csf-2-example-starter.md本示例的完整文件形态含 default export 与 args 注解docs/_snippets/csf-2-example-primary-dark-story.md 与 docs/_snippets/csf-2-example-title.mdCSF 2 侧的故事派生与标题声明docs/_snippets/csf-3-example-render.md、docs/_snippets/csf-3-example-default-render.md、docs/_snippets/csf-3-example-starter.md与本文逐渲染器对照的 CSF 3 版本编写故事的一般性指南见 docs/writing-stories。【免费下载链接】storybookStorybook is the industry standard workshop for building, documenting, and testing UI components in isolation项目地址: https://gitcode.com/GitHub_Trending/st/storybook创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表