资讯动态

Storybook 用 MDX 单页文档编排多组件实战:Meta、Canvas、Story Doc Block 的协同用法

发布时间:2026/9/10 20:20:35 来源:尧图企业网站定制
Storybook 用 MDX 单页文档编排多组件实战Meta、Canvas、Story Doc Block 的协同用法【免费下载链接】storybookStorybook is the industry standard workshop for building, documenting, and testing UI components in isolation项目地址: https://gitcode.com/GitHub_Trending/st/storybookMDX 文档页的核心优势在于它把 Markdown 的可读性、CSF 中已有的 story 以及任意 JSX/React 组件放在同一个文件中编排。本指南围绕 Storybook 文档中Working with multiple components这一场景讲解如何在一个Page.mdx文件中同时引用 Page、List、ListItem 多个组件的 story 文件并借助Meta、Canvas、Story三个 Doc Block 完成挂接、带源码渲染与纯渲染。读完本文你将掌握多组件 MDX 文档的完整写法、meta属性的适用时机以及不同框架含 Svelte CSF下的文件组织差异。为什么需要一个 MDX 文档多个组件Storybook 把组件文档拆成两种格式CSF 负责用export精炼地定义每个组件状态storyMDX 则负责书写结构化文档并与交互式 JSX 元素组合。当你要为 Page、List、ListItem 这类互相嵌套的复合组件编写一份总览型文档时常见诉求是在同一个文档页里既介绍 Page 的布局用途又顺带展示 List 的填充状态和 List Item 的起始状态。Storybook 对此开箱即用MDX 文件可以导入任意数量的 CSF 文件并在正文中用 Doc Block 引用其中任意一个 story。内部实现上文档页面中描述为Storybook 会自动查找这些 story 的元数据并把它们与既有文档内容组合渲染。换句话说一份 MDX 的挂接主体只能有一个组件通过Meta of决定它出现在哪个组件的 story 列表旁但它可以旁路渲染任意其他 CSF 文件里的 story——前提是你给相关 Doc Block 传入正确的meta指向。完整示例一个引用三个组件 story 的 Page.mdx该示例来自 docs/_snippets/storybook-auto-docs-mdx-file.md它在官方文档中被用于说明多组件 MDX 写法。下面先给出最常见的通用 CSF变体import { Canvas, Meta, Story } from storybook/addon-docs/blocks; import * as ListStories from ./List.stories; import * as ListItemStories from ./ListItem.stories; import * as PageStories from ./Page.stories; Meta of{PageStories} / # Page Page is a layout container that is used to position children in predetermined areas. Its often used to apply consistent positioning for content across pages in an application ## Usage Canvas of{PageStories.Basic} / # List List is a grouping of related items. List can be ordered with multiple levels of nesting. ## Usage Story of{ListStories.Filled} / # List Item List items are used to group related content in a list. They must be nested within a List component. ## Usage Story of{ListItemStories.Starter} meta{ListItemStories} /Svelte CSF 变体如果你的 Svelte 项目采用把 story 直接写在.svelte文件中的写法Svelte CSF则导入路径需要指向对应的.stories.svelte文件import { Canvas, Meta, Story } from storybook/addon-docs/blocks; import * as ListStories from ./List.stories.svelte; import * as ListItemStories from ./ListItem.stories.svelte; import * as PageStories from ./Page.stories.svelte; Meta of{PageStories} / # Page Page is a layout container that is used to position children in predetermined areas. Its often used to apply consistent positioning for content across pages in an application ## Usage Canvas of{PageStories.Basic} / # List List is a grouping of related items. List can be ordered with multiple levels of nesting. ## Usage Story of{ListStories.Filled} / # List Item List items are used to group related content in a list. They must be nested within a List component. ## Usage Story of{ListItemStories.Starter} meta{ListItemStories} /CSF 3 变体若 Svelte 项目采用与 React/Vue 一致的、以.stories文件组织 story 的 CSF 3 写法导入路径回退到普通 CSF 文件即可import { Canvas, Meta, Story } from storybook/addon-docs/blocks; import * as ListStories from ./List.stories; import * as ListItemStories from ./ListItem.stories; import * as PageStories from ./Page.stories; Meta of{PageStories} / # Page Page is a layout container that is used to position children in predetermined areas. Its often used to apply consistent positioning for content across pages in an application ## Usage Canvas of{PageStories.Basic} / # List List is a grouping of related items. List can be ordered with multiple levels of nesting. ## Usage Story of{ListStories.Filled} / # List Item List items are used to group related content in a list. They must be nested within a List component. ## Usage Story of{ListItemStories.Starter} meta{ListItemStories} /三个变体的正文结构完全一致差异仅在于 story 文件的命名与导入来源这也是 Svelte 框架同时存在List.stories.sveltestory 直接嵌在组件文件里与独立 CSF 文件两种作者工作流的体现。逐段拆解这份 MDX 是如何工作的1. 从 Doc Blocks 库导入三个块import { Canvas, Meta, Story } from storybook/addon-docs/blocks;Meta、Canvas、Story都属于 Storybook addon-docs 暴露的 Doc Block。它们的导出入口位于 code/addons/docs/src/blocks/blocks/index.ts其中通过export * from ./Meta、export * from ./Canvas、export * from ./Story等形式统一对外提供同时还有ArgTypes、Controls、Description、Source、Stories等其他块。Canvas与Story的关系是Canvas是Story的包装器额外提供工具条与自动生成的源码片段。2. 用命名空间导入把每个 CSF 文件整体引入import * as ListStories from ./List.stories; import * as ListItemStories from ./ListItem.stories; import * as PageStories from ./Page.stories;这里必须使用import * as引入 CSF 文件的全部具名导出每个导出就是一个 story而不是默认导出或直接引入组件本身。Doc Block 在运行时需要通过这个命名空间对象去查找 story 的元数据parameters、args、loaders、decorators 等。3. 用Meta决定文档挂接在哪个组件下Meta of{PageStories} /Meta本身不渲染任何可见内容它的作用有两个详见 Doc Block: Metaattached挂接通过of把 MDX 文档与某个 CSF 文件绑定使文档出现在该组件的 story 列表旁侧边栏条目默认名为docs.defaultName配置值默认Docs可用Meta of{PageStories} nameInfo /覆盖unattached不挂接只提供Meta titlepath/to/node /把文档放到导航层级中的任意位置。需要特别强调的是官方反复提示的约束of必须引用 story 文件的完整导出集合import * as PageStories得到的那个命名空间而不是组件本身或 CSF 的 default export否则生成的文档可能出现渲染问题。在本例中整个 MDX 只通过PageStories这一个 CSF 文件完成挂接因此文档节点会被放在 Page 组件之下List 与 ListItem 的 story 则是借用到这篇文档里的。4. Markdown 正文与标题MDX 默认支持 CommonMark 规范的标准 Markdown若需表格、脚注等 GFM 特性需在.storybook/main中启用remark-gfm插件参见 Troubleshooting 一节。示例中的# Page、## Usage等标题即纯 Markdown 语法。需要留意MDX 的块之间要用空行分隔不同语言块混排时缺少空行常会触发难以理解的解析错误。5.Canvas带工具条与源码的交互式演示Canvas of{PageStories.Basic} /Canvas块是 Story 块的包装它给 story 加一个带边框的画布容器自动提供可以展开的Source源码片段并可通过工具栏与 story 交互。常用 props 包括of指定渲染哪条 storymeta指定 story 所属的 CSF 文件用于渲染未通过Meta挂接的故事sourceState取hidden | shown | none控制源码面板初始状态默认parameters.docs.canvas.sourceState或hiddenlayout取centered | fullscreen | padded控制画布内 story 的布局默认paddedwithToolbar是否渲染可交互的工具条。值得注意的是旧版Canvas可以以子元素方式塞入任意组件该用法已被弃用现在的Canvas只接受单条 story。所以当你需要只展示故事本体、不要边框和源码面板时就应改用Story块。6.Story只渲染故事本身Story of{ListStories.Filled} /Story块会在 MDX 上下文中以全部注解parameters、args、loaders、decorators、play function生效的方式渲染任意一条 CSF story。默认情况下文档中的 story不会自动执行 play function因为同一文档页内多个 story 同时渲染play 函数可能互相干扰例如抢焦点或滚动屏幕若确认某个 play 函数安全可传入autoplay打开见 Doc Block: Story。7.meta属性渲染非挂接CSF 里的 storyStory of{ListItemStories.Starter} meta{ListItemStories} /这是本示例最有价值的一行MDX 文件只通过Meta of{PageStories} /挂接在 Page 之下但 ListItem 的Starterstory 来自另一个 CSF 文件。此时必须为Story显式传入meta{ListItemStories}告诉 Storybook 这条 story 属于哪个 CSF 命名空间否则 Storybook 无法在挂接组件上下文之外解析出该 story 的元数据。同理Canvas也有同名metaprop。官方 doc-block-meta.mdx 中的反例场景即是如此某 MDX 主要介绍 Button但仍可借助Canvas of{HeaderStories.LoggedIn} meta{HeaderStories} /顺带渲染 Header 组件的故事。这也是单页文档编排多个组件的通用模式一个of决定挂接位置多个meta决定可引用的故事来源。多组件文档在何时最有用从官方文档页 docs/writing-docs/mdx.mdx 的上下文看这种写法常被用于以下场景复合组件族总览Page、List、ListItem 这类组件有严格的嵌套约束例如 List Item 必须嵌套在 List 内单页文档便于图文并茂地展示层级关系与使用规范按文件系统组织文档若需要脱离组件写独立文档如测试指南、入门说明可以不写Meta让 Storybook 依据 MDX 文件物理位置 auto-title 规则 推断侧边栏位置渲染为Docs条目覆盖自动生成的文档通过在stories配置中放置 MDX 文件即可覆盖同名组件的 Autodocs 页面官方建议此时移除对应的tags配置以免冲突。若想用 MDX 承载多组件文档先要在.storybook/main的 stories 配置中把.mdx纳入扫描范围参考 storybook-auto-docs-main-mdx-config.md 中的stories写法确保 Storybook 能发现并索引你的文档文件。从源码看 Doc Block 的渲染机制如果你希望进一步理解这些块的内部行为可以直接阅读 addon-docs 的源码实现code/addons/docs/src/blocks/blocks/Meta.tsx负责建立MDX ↔ CSF的上下文绑定不输出可见 UIcode/addons/docs/src/blocks/blocks/Canvas.tsx组合了Story与Source并提供工具条与布局控制code/addons/docs/src/blocks/blocks/Story.tsx负责真正查找并渲染 storycode/addons/docs/src/blocks/blocks/index.ts集中导出全部 Doc Block也就是import ... from storybook/addon-docs/blocks的实际解析目标。对 Svelte CSF 文件.stories.svelte与普通 CSF 3 文件的差异仓库中的配套片段如 checkbox-story-csf.md也保留了 Svelte CSF / CSF 3 两种 tab 的对应版本可作为对照参考。小结与延伸在单个 MDX 页中编排多个组件的要点可归纳为四步整体import * as引入各 CSF 文件 → 用Meta of{主组件Stories} /决定文档的挂接位置 → 用Canvas需要工具条与源码或Story只渲染本体引用任意 story → 对非挂接 CSF 的 story 记得补metaprop。更多相关内容可继续查阅多组件文档所属的完整章节docs/writing-docs/mdx.mdxMDX 引入 story 的导入、Meta、定义、Story 四段式拆解storybook-auto-docs-mdx-docs-imports.md、storybook-auto-docs-mdx-docs-meta-block.md、storybook-auto-docs-mdx-docs-definition.md、storybook-auto-docs-mdx-docs-story.md各 Doc Block 的完整 props 参考Meta、Canvas、Story了解自动生成文档与 MDX 的搭配docs/writing-docs/autodocs.mdx。【免费下载链接】storybookStorybook is the industry standard workshop for building, documenting, and testing UI components in isolation项目地址: https://gitcode.com/GitHub_Trending/st/storybook创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价