尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

用 Storybook Args 一个对象切换 Button 全部状态:React / Vue / Angular 跨框架写法与三层优先级全解

用 Storybook Args 一个对象切换 Button 全部状态:React / Vue / Angular 跨框架写法与三层优先级全解 用 Storybook Args 一个对象切换 Button 全部状态React / Vue / Angular 跨框架写法与三层优先级全解【免费下载链接】storybookStorybook is the industry standard workshop for building, documenting, and testing UI components in isolation项目地址: https://gitcode.com/GitHub_Trending/st/storybook你手里有个Button要演示出紫色主按钮、灰色次按钮、加载中、禁用这几种样子。最笨的办法是往源码里塞四个if分支不必。Storybook 的Args机制让你用一个普通对象{ primary: true, label: Button }就能把同一份组件切成不同状态一行组件源码都不用碰。下面把怎么用和为什么能用一次讲清。一个 args 对象能换掉多少种按钮状态一句话结论args 就是一张渲染参数表键是 prop 名值是这个状态该长什么样。故事文件里export出来的每个对象就是一个状态它带的args决定组件怎么被喂料。最小的可运行故事去掉所有类型糖之后只剩两行export const Primary { args: { primary: true, label: Button }, };改primary为false、label为别的字符串按钮的视觉状态立刻跟着变——因为 Storybook 把这张表原样送进了组件。记住这个形状后面所有框架只是在怎么把表送进组件上做文章。React 版 Button 故事怎么写React 里 args 就是 props 本身不需要额外渲染函数。下面是一份完整可跑的 TS 故事文件JS 项目删掉satisfies和type那两行即可// 只保留 TS 写法把 react-vite 换成你实际用的框架包 import type { Meta, StoryObj } from storybook/react-vite; import { Button } from ./Button; const meta { component: Button, } satisfies Metatypeof Button; // 让 meta 的字段被 Button 的真实 props 约束 export default meta; type Story StoryObjtypeof meta; // 从此 args 有自动补全和类型检查 export const Primary: Story { args: { primary: true, label: Button, }, };差异点React 靠typeof Button把类型反推出来所以连render都不用写args 直接当 props 消费。这是三个框架里最省事的一个。Vue 3 版 Button 故事怎么写Vue 组件是.vue单文件Storybook 猜不出怎么把普通对象绑上去所以必须手写一个render用v-bind当那根连接线import type { Meta, StoryObj } from storybook/vue3-vite; import Button from ./Button.vue; const meta { component: Button, } satisfies Metatypeof Button; export default meta; type Story StoryObjtypeof meta; export const Primary: Story { // 把整张 args 表透传给组件等价于模板里的 :props render: (args) ({ components: { Button }, setup() { return { args }; }, template: Button v-bindargs /, }), args: { primary: true, label: Button, }, };差异点相比 ReactVue 多了render但 args 的形状一模一样v-bindargs就是把表整个贴到组件上的 Vue 语法。Angular 版 Button 故事怎么写Angular 连render都省了args会被直接绑到组件的Input上。类型桥接走的是另一条路——把组件类本身丢给Metaimport type { Meta, StoryObj } from storybook/angular; import { Button } from ./button.component; const meta: MetaButton { component: Button, // 类型参数直接吃组件类args 与 Input 自动对齐 }; export default meta; type Story StoryObjButton; export const Primary: Story { args: { primary: true, label: Button, }, };差异点React 是先typeof Button再反推Angular 是直接把类当类型参数。两种绕法目的相同让 args 跟组件输入保持类型同步写错键名时编辑器就红给你看。三种框架的 component、render、类型桥接对比框架component指向render必需类型桥接方式React组件模块Button否args 即 propssatisfies Metatypeof ButtonStoryObjtypeof metaVue 3.vue单文件组件是v-bind透传同 ReactAngular组件类Button否自动绑InputMetaButton直接传类一张表看下来真正的区别只有两处要不要手写 render以及类型从哪来。args 本身跨框架通用这正是它能一改全改的根基。三层 args 谁覆盖谁global、component、story 优先级当同一个参数可能在三个地方被定义时谁说了算规则是越具体越优先层级写在哪作用范围优先级story args单个故事对象只影响该故事最高component argsmeta的args键该组件所有故事中global args.storybook/preview默认导出所有组件所有故事最低这不是口头约定源码里写得很直白。在 code/core/src/preview-api/modules/store/csf/prepareStory.ts 中故事准备阶段按固定顺序展开三层const passedArgs: Args { ...projectAnnotations.args, // 全局 ...componentAnnotations.args, // 组件 ...storyAnnotations?.args, // 故事写在最后覆盖前两者 };对象展开后者吃前者所以故事级永远赢。这段逻辑发生在渲染之前、和组件 props 声明完全解耦也解释了为什么用 args 切状态永远不需要改组件源码。另外注意合并完的表还会再过一遍argsEnhancers流水线比如从argTypes推导默认值就是在这一步注入的。提醒一句如果你要的是用户在工具栏一键切换的全局开关典型如主题用globals比 global args 更合适——前者能被工具栏控件直接驱动后者是写死的默认值。实战技巧args 复用、URL 覆写、Controls 实时联动① 对象展开复用。args 就是个普通对象想派生一个长得差不多的新状态抄一份再改单个键即可export const PrimaryLongName: Story { args: { ...Primary.args, // 先搬走 Primary 的全部参数 label: 很长的按钮文本, // 只覆盖一个键 }, };如果绝大多数故事共享一组值别在故事里各抄一遍把它上提到meta的argscomponent args更干净。② URL 直接覆写参数。不想开页面调 Controls把参数拼进 query 就能复现现场方便贴给同事?path/story/button--primaryargslabel:你好;size:large解析规则值以;分隔写成key: value会按argTypes自动转回对应类型对象和数组都支持。特殊值要加!前缀比如nil:!null表示空值颜色写!hex(...)/!rgba(...)。出于 XSS 防护URL 里的值只认字母数字、空格、下划线和连字符其余会被静默忽略——复杂值请走 Controls 面板或argTypes.mapping。③ Controls 与 useArgs 双向联动。只要故事用了 argsControls 面板就能实时改值并触发重渲染回调事件会记进 Actions 面板。反过来当你要组件内部状态改 → Controls 选中态跟着变就在渲染函数里用useArgsrender: (args) { const [{ isChecked }, updateArgs] useArgs(); return ( Checkbox {...args} isChecked{isChecked} onChange{() updateArgs({ isChecked: !isChecked })} // 点组件反写 args / ); }这里有个坑必须说在渲染函数里用 Storybook 的 hooks 时别再混 React 自己的useState/useEffect/useRef。React 那套副作用不走 Storybook 的 hook 上下文二次渲染就会炸状态统一交给storybook/preview-api的等价 hooks。心智模型与延伸阅读把整件事压缩成一句话写故事 描述一组 args 一个渲染目标。args 是输入契约render或框架的自动绑定是执行器Storybook 在 prepare 阶段把三层 args 合并、增强后喂给执行器于是同一个组件才能被同一份源码反复切成 N 种状态。你真正要做的只是把想要什么状态写成一张表。想继续往下挖三个入口参数机制权威出处docs/writing-stories/args.mdx三层作用域、组合、URL 覆写、mapping、useArgs全在这。故事到底是什么的第一课docs/get-started/whats-a-story.mdx配了运行截图。合并顺序的底层实现code/core/src/preview-api/modules/store/csf/prepareStory.ts看prepareStory如何把故事 装饰器 参数打包成一个可复用的无状态渲染函数。【免费下载链接】storybookStorybook is the industry standard workshop for building, documenting, and testing UI components in isolation项目地址: https://gitcode.com/GitHub_Trending/st/storybook创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表