用 Storybook 构建 UI 组件:一条命令从「能跑」到「敢上线」
2026/9/7 17:16:42 网站建设 项目流程

用 Storybook 构建 UI 组件:一条命令从「能跑」到「敢上线」

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

你改了 Button 的一个属性,三个页面开始报错;设计师问"错误态长什么样",你只能启动整个应用,点四层菜单再截图。Storybook 是 UI 组件隔离开发的工作台:把组件从应用里拉出来,为每种状态写一个故事,测试、文档、分享都在同一个地方完成。

先把组件从应用里拉出来:三个逼你动手的场景

组件改了,谁被改崩?

你给一个输入组件加了新属性,只在登录页验证过。两周后才发现注册页、资料页、管理后台都在用它,而且各自用了不同的组合方式。组件是全项目的"公约数",它的测试覆盖却只有一页。

设计师要一个按钮,你得启动整个应用

"帮我看下禁用态、带图标、深色背景下的按钮。"回答这个问题的成本,是启动应用、登录、导航四级菜单、再截图。而对方要的其实只是"一个组件的某个状态"。

新人上手,页面根本跑不起来

新同事拿到仓库说"先跑起来看看"。二十分钟后:数据库没连上、登录被拦、mock 服务没起。组件代码本身只有几百行,它依赖的环境却是整个业务系统。

Storybook 工作台:左侧故事树,右侧是组件画布与源码,整个组件库的状态一览无余

🚀 从第一条命令到第一个组件故事

敲下第一条命令后会发生什么

在你的项目目录里运行:

npx storybook@latest init

它是一个交互式向导:自动检测你用的是 React、Vue 3、Angular 还是 Svelte,问几个问题,然后安装依赖、生成.storybook/配置目录,并写好 Button、Header、Page 三个示例组件和对应的故事文件。

init 之后的 onboarding 向导:选框架、选配置,剩下的自动生成

打开 localhost 后你看到什么

然后启动它:

npm run storybook

浏览器自动打开 localhost:6006。左边侧栏是故事树,三个示例组件已经挂在那里;点开Button / Primary,组件就单独渲染在画布里。没有登录、没有路由、没有数据请求,这个页面上只有它自己——这是它给你最重要的感觉。

改一个属性,立刻看到效果

故事文件本身是个很普通的对象:

export default { component: Button }; export const Primary = { args: { label: 'Primary' } };

第一行叫 meta,声明这个文件属于哪个组件;第二行是一个故事:Primary是故事名,args是传给组件的一组参数。保存文件,画布热更新,不用刷新。

⚡️ 建立心智模型:故事到底是什么

故事是组件的「产品照」

一个类比:故事就是组件的产品照。每张照片有名字(Primary、Disabled、Loading),展示一个固定状态,照片下方的标签上列着这次用了哪些参数。写故事就是拍照,而 Controls 面板让你随时改参数、重拍一张。

概念一句话定义对你意味着什么
Story组件的一种可渲染状态「悬停+超长文本」变成独立可访问的页面
args传给组件的参数集在右侧面板改属性,不用动代码
Controls由 args 生成的 UI改完可以直接存成新故事
Docs 页从故事自动生成的文档属性表格和代码永远同步
Decorator故事外层的包裹器包一次主题 Provider,所有故事都生效

故事这个概念在 React、Vue 3、Angular、Svelte、Web Components 里完全一致,只是文件后缀和写法不同——换框架不用重新学。

Controls 面板:args 里定义的 label 变成输入框,改完立刻看到画布变化

📌 把 Storybook 推进团队:个人、小组、组织三档

个人:先让一个组件「不崩」

  • 挑你最复杂的组件,把默认、空数据、错误三类状态写成故事
  • 开发时开着 Controls 调状态,调出有意思的组合就"存为新故事"
  • 加一条交互测试(用 play 函数写点击断言),行为坏了 CI 第一时间告诉你

小组:把故事变成评审准入

  • 立一条规矩:改组件的 PR 必须带上对应故事更新,否则不评审
  • 视觉回归和交互测试进 CI,组件的每个状态都成为回归基线
  • 把 Storybook 链接直接发给 QA 和设计师,验收不用启动业务应用

交互测试:测试步骤逐条打勾,失败能精确定位到具体某一步

组织:把它变成设计系统

  • 发布统一实例,产品线按版本号锁定组件版本,升级有节奏
  • 定制主题与品牌色,跨团队组件有一个统一入口
  • 开启无障碍(a11y)插件做发布前全量检查,合规过程可审计

Docs 页:属性表、示例和使用说明都由代码生成,设计师可直接验收

🔧 排掉新手最常踩的三个坑:现象、原因、解法

为什么 init 完页面是空的?

现象:服务起来了,左侧栏一个故事都没有。原因:故事靠 glob 匹配发现,老项目里组件旁边没有.stories.ts(x)文件,它就不会被索引到。解法:打开.storybook/main检查stories字段的 glob 是否覆盖你的源码目录,然后给组件补一个故事文件。

为什么组件样式没了?

现象:应用里组件样式正常,故事里却像裸 HTML。原因:隔离环境不会自动继承应用的 CSS 构建,Tailwind、CSS Modules、主题变量都没被加载。解法:让 builder 复用项目的 Vite 或 Webpack 样式配置,静态资源路径写进staticDirs

为什么故事突然报 Provider 缺失?

现象:故事里抛出"undefined 不可读",或主题 Provider 找不到的错误。原因:组件依赖上层 Context——主题、路由、登录态,应用里天然存在,隔离环境里没人提供。解法:在preview.tsx里全局加一个 decorator 包上 Provider,所有故事一次生效,不用逐个改。


今天就能做的最小一步:打开终端,运行npx storybook@latest init,十分钟后你就有了自己的组件沙箱。想读源码的话:

git clone https://gitcode.com/GitHub_Trending/st/storybook

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

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

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

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

立即咨询