Storybook Addon API 深度解析:使用 `getUrlState()` 读取与重建应用 URL 状态
2026/9/10 14:14:16 网站建设 项目流程

Storybook Addon API 深度解析:使用getUrlState()读取与重建应用 URL 状态

【免费下载链接】storybookStorybook is the industry standard workshop for building, documenting, and testing UI components in isolation项目地址: https://gitcode.com/GitHub_Trending/st/storybook

本文基于 Storybook 仓库中的 addon 开发文档与源码,系统讲解 addon 注册回调中获取的api.getUrlState()方法。你将理解它返回哪些字段、如何在自定义 addon 中读取当前 URL 状态(含当前 story、viewMode 与自定义 query 参数),并掌握它与setQueryParamsgetQueryParamapplyQueryParams等兄弟 API 配合构建可分享链接的完整思路。

一、getUrlState()是什么

在开发 Storybook addon 时,你通常需要在 manager(管理界面)侧读取"当前应用处于什么状态":正在展示哪一个 story、处于story还是docs视图模式、URL 上挂了哪些自定义查询参数、以及完整的 URL 是什么。

api.getUrlState()正是为此提供的 API。官方文档将它的签名写作api.getUrlState(overrideParams),语义为"获取应用 URL 状态,包括任何被覆盖的或自定义的参数值"。它可以在addons.register()的注册回调中被调用,因为该回调的第二个参数就是 addon 可用的 manager API 对象。

在 docs/addons/addons-api.mdx 的 "Storybook API" 小节中,它被放在setQueryParams/getQueryParam之后、getStoryHrefs之前,共同构成一套"读写 URL 状态"的工具集。

二、最小用法示例

原文档 storybook-addons-api-geturlstate.md 给出的标准示例位于 addon 的 manager 入口文件中:

// my-addon/src/manager.js|ts addons.register('my-organisation/my-addon', (api) => { const href = api.getUrlState({ selectedKind: 'kind', selectedStory: 'story', }).url; });

示例拆解:

  • addons.register('my-organisation/my-addon', cb):注册一个 addon,名称需保持全局唯一(习惯使用组织名/addon名的命名空间形式)。
  • 回调参数api:manager 侧完整 API,getUrlState是其中的方法之一。
  • getUrlState(...).url:取回结果的url字段——即当前 Storybook 应用在地址栏中的完整 URL 字符串。

需要说明的是:文档示例中传入的selectedKind/selectedStory属于早期(v5 时代)Storybook 以selectedKind=...&selectedStory=...形式定位 story 时的遗留参数写法,当前文档保留该片段用于展示"以覆盖参数请求 URL 状态"这一历史接口形态;而在现代 Storybook 中,story 的定位已统一为?path=/story/...。因此对当前版本来说,最稳妥、最有价值的调用方式是直接读取返回值:

// my-addon/src/manager.js|ts addons.register('my-organisation/my-addon', (api) => { // 获取完整 URL 状态 const state = api.getUrlState(); // 取完整 URL:https://host/path/?path=/story/button--primary&args=label:Hello const href = state.url; // 其余字段按需使用(见下文字段说明) const { path, viewMode, storyId, queryParams, hash } = state; });

三、返回值的字段结构

从当前仓库源码 code/core/src/manager-api/modules/url.ts 中SubAPI接口的类型声明可以看到,getUrlState返回对象包含以下字段:

字段类型含义示例
urlstring当前应用完整 URL/index.html?path=/story/button--primary&args=label:Hello
pathstringURL 中的路径段(含/story/前缀的 story 定位)/story/button--primary
viewModestring \| undefined当前视图模式'story''docs'
storyIdstring \| undefined当前 story 的 ID'button--primary'
queryParamsQueryParams自定义查询参数(不含布局类参数,见下文){ args: 'label:Hello', globals: 'theme:light' }
hashstring当前 location 的 hash''

类型声明原样如下:

getUrlState: () => { queryParams: QueryParams; path: string; hash: string; viewMode?: string; storyId?: string; url: string; };

用途提示:

  • url:最适合用来拼出"当前所处状态"的可分享/可回退链接;
  • path+hash+queryParams:在实现"追加一个参数后原地跳转"这类逻辑时,可以先把状态拆开、合并新参数、再交给导航方法;
  • storyId/viewMode:addon 需要感知用户正在看哪个 story、处于文档还是 story 视图时使用。

四、源码实现:URL 状态从哪来

4.1 实现本体

getUrlState的实现位于 code/core/src/manager-api/modules/url.ts,它并不自行解析 location,而是直接读取 manager 的全局 store 状态:

getUrlState() { const { location, path, customQueryParams, storyId, url, viewMode } = store.getState(); return { path, hash: location?.hash ?? '', queryParams: customQueryParams, storyId, url, viewMode, }; },

这意味着getUrlState()返回的永远是当前 store 中已被同步过的、真实的 URL 状态,而不是临时计算结果。它依赖的store.getState()快照由 URL 模块在初始化时(initialUrlSupport)以及每次导航时统一维护,因此不同调用点拿到的结果彼此一致。

4.2 自定义 query 参数如何界定

queryParams(即 store 中的customQueryParams)来源于地址栏查询串,但有一类"布局/导航参数"会被排除在外。源码通过白名单常量实现这一过滤(code/core/src/manager-api/modules/url.ts):

// URL query params the manager consumes for layout/navigation. // Everything else is a custom param passed through to the preview iframe. const LAYOUT_QUERY_PARAM_KEYS = ['full', 'panel', 'nav', 'shortcuts', 'addonPanel', 'tabs', 'path']; export const getCustomQueryParams = (location) => omit(queryFromLocation(location), LAYOUT_QUERY_PARAM_KEYS);

也就是说:fullpanelnavshortcutsaddonPaneltabspath这些由 manager 消费的键不会出现在getUrlState().queryParams中;而像argsglobals以及 addon 通过setQueryParams写入的自定义参数则会保留,并被透传到 preview iframe 使用。

4.3 与 URL 解析/构建基础设施的关系

模块顶层还引入并复用了 router 工具queryFromLocationbuildNavigationUrl(code/core/src/manager-api/modules/url.ts、lib/url.ts 中的 buildNavigationUrl),URL 模块整体是这些底层工具之上的一层"状态化封装"——addon 开发者无需关心 URL 语法细节,只需通过 API 读写。

五、与相关 API 的组合使用

getUrlState所在的 URL 模块同时暴露了一组配套 API(见 code/core/src/manager-api/modules/url.ts 的SubAPI实现),它们共同覆盖"读状态、改参数、发起导航"的完整闭环:

API作用关键实现细节
getQueryParam(key)读取单个自定义查询参数的值直接读store.getState().customQueryParams[key],不存在返回undefined
setQueryParams(input)写入/更新查询参数(临时存储),参数置null/undefined表示删除与原值deepEqual相同则跳过,变化后写 store 并通过 channel 广播UPDATE_QUERY_PARAMS事件
applyQueryParams(input, options)设置参数并触发导航内部先调getUrlState()取回path/hash/queryParams,合并后导航
navigateUrl(url, options)直接导航到指定 URLplain: true方式交给 router
getStoryHrefs(storyId, options?)为某个 story 生成 manager/preview 两个链接支持baseinheritArgsinheritGlobalsrefIdviewMode等选项

一个典型的"读出当前状态 → 加上自定义参数 → 生成新链接"示例:

// my-addon/src/manager.js|ts import { addons } from 'storybook/manager-api'; addons.register('my-organisation/my-addon', (api) => { const state = api.getUrlState(); // 1) 单独读取某个参数 const currentHighlight = api.getQueryParam('highlighted'); // 2) 写入参数并触发一次导航(自动合并当前位置与已有参数) api.applyQueryParams({ highlighted: currentHighlight === 'true' ? null : 'true' }); // 3) 由当前完整 URL 状态构造可分享链接(例如加上跟踪标记) const { url } = api.getUrlState(); const shareable = `${url}${url.includes('?') ? '&' : '?'}utm_source=my-addon`; console.log(shareable); });

六、使用注意点

  1. 运行环境getUrlState属于 manager 侧 API,只能在 addon 的 manager 入口(如my-addon/src/manager.js|ts)中使用,不要与 preview(iframe)侧 API 混用。官方在 docs/addons/addons-api.mdx 中将其归入addons.register回调提供的 API 之列。
  2. 参数语义:文档标题中的overrideParams与示例里的selectedKind/selectedStory反映的是历史版本"用 kind/story 覆盖 URL 状态"的用法;从本仓库当前SubAPI类型声明与实现看,方法调用时不读取参数,直接返回 store 中同步好的完整状态。若你的 addon 需要兼容文档示例写法,应以"读取.url字段"为可靠基线。
  3. 返回值是快照getUrlState()返回的是调用时刻的 URL 状态副本。若需要在用户每次切换 story 后都拿到最新值,应配合api.on(...)之类的事件订阅在回调中重新调用。
  4. 自定义参数范围queryParams中不含full/panel/nav/shortcuts/addonPanel/tabs/path等布局键,不要期望从该字段拿到这七类参数。

七、延伸阅读

  • 完整的 addon API 索引见 docs/addons/addons-api.mdx,其中getUrlState前后相邻的setQueryParamsgetQueryParamgetStoryHrefs均配套有独立 snippet,可对照阅读:
    • storybook-addons-api-getqueryparam.md
    • storybook-addons-api-setqueryparams.md
    • storybook-addons-api-disablequeryparams.md
  • URL 状态模块的核心源码位于 code/core/src/manager-api/modules/url.ts(类型声明与实现分别在SubAPIinit导出中),URL 解析/构建工具在 code/core/src/manager-api/lib/url.ts。

小结getUrlState()是 addon 在 manager 侧获取"当前 Storybook 到底是什么状态"的标准入口。理解它返回的六个字段、明白queryParams与布局参数的边界、再配合setQueryParams/applyQueryParams/getStoryHrefs这一组 URL 读写工具,你就可以在 addon 中可靠地实现"读取 → 改写 → 导航/分享"的完整链路。

【免费下载链接】storybookStorybook is the industry standard workshop for building, documenting, and testing UI components in isolation项目地址: https://gitcode.com/GitHub_Trending/st/storybook

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询