如何从组件的操作中动态改变 Storybook v6 中的“args”?

Posted

技术标签:

【中文标题】如何从组件的操作中动态改变 Storybook v6 中的“args”?【英文标题】:How to dynamically mutate "args" in Storybook v6 from the component's action? 【发布时间】:2020-12-21 18:44:29 【问题描述】:

让我们看看我们有一个简单的组件ToggleButton

const ButtonComponent = Vue.component('ButtonComponent', 
  props: 
    value: Boolean
  ,

  methods: 
    handleClick() 
      this.$emit('toggle');
    
  ,

  template: `
    <button 
      :class="value ? 'on' : 'off'"
      @click="handleClick"
    >
      Toggle
    </button>`
);

以及该组件的故事:

import ToggleButton from './ToggleButton.vue';

export default 
  title: 'ToggleButton',
  component: ToggleButton,

  argTypes: 
    onToggle: 
      action: 'toggle' // <-- instead of logging "toggle" I'd like to mutate `args.value` here
    
  
;

export const Default = (_args,  argTypes ) => (
  components:  ToggleButton ,
  props: Object.keys(argTypes),

  template: `
    <ToggleButton
      :value="value"
      :toggle="onToggle"
    />
  `
);

Default.args = 
  value: false

我想要实现的是处理故事中的toggle 动作并更改我在Default.args 对象中使用的value,通过将类名从.off 更改为@987654328 来更改按钮样式@。

【问题讨论】:

你有没有偶然发现这个? @SpaceOso 不幸的是没有。我在故事中为类似的东西创建了一个包装器组件(包装器内的控制道具),但它与我正在寻找的不完全相同。 @Ky6uk 你能分享一下那个组件包装器最终的样子吗?我正在尝试自己解决这个问题 @MaximFedotov 我刚刚在ButtonComponent.stories.ts 中创建了一个新的Vue 组件,比如说const ControlComponent = Vue.component('ControlComponent', components: ButtonComponent );,其中的动态属性正在被ButtonComponent 改变。然后用它代替ButtonComponent 【参考方案1】:

我遇到了同样的问题,并且一直在寻找几天,直到我偶然发现了这个 github 帖子: https://github.com/storybookjs/storybook/issues/12006

目前在我的 React 中(我确信 vue 方法会类似),我执行以下操作:

import React from 'react';
import CheckboxGroupElement from '../CheckboxGroup';
import  STORYBOOK_CATEGORIES  from 'elements/storybook.categories';
import  useArgs  from '@storybook/client-api';

export default 
  component: CheckboxGroupElement,
  title: 'Components/CheckboxGroup',
  argTypes: 
    onChange: 
      control: 'func',
      table: 
        category: STORYBOOK_CATEGORIES.EVENTS,
      ,
    ,
  ,
  parameters:  actions:  argTypesRegex: '^on.*'  ,
;

const Template = (args) => 
  const [_, updateArgs] = useArgs();

  const handle = (e, f) => 
// inside this function I am updating arguments, but you can call it anywhere according to your demand, the key solution here is using `useArgs()`
// As you see I am updating list of options with new state here
    console.log(e, f);
    updateArgs( ...args, options: e );
  ;
  return <CheckboxGroupElement ...args onChange=handle />;
;

export const CheckboxGroup = Template.bind();
CheckboxGroup.storyName = 'CheckboxGroup';
CheckboxGroup.args = 
//Here you define default args for your story (initial ones)
  controller:  label: 'Group controller' ,
  options: [
     label: 'option 1', checked: true ,
     label: 'option 2', checked: false ,
     label: 'option 3', checked: false ,
  ],
  mode: 'nested',
;

【讨论】:

Storybook 通常是这样的,不是吗?您正在寻找文档中从未提及的功能,只是为了在其源代码或 GitHub 问题中找到它。 这很好用,但是 args 状态似乎与控件状态不同步。 @T.Gaud 你的问题到底是什么样的? @ProllyGeek 如果我在触发 onClick 时使用 useArgs 更改组件的状态,则控件插件(包含在 storybook-essentials 中)不会反映更新后的状态。 @T.Gaud 你说的是画布标签中的操作面板吗?

以上是关于如何从组件的操作中动态改变 Storybook v6 中的“args”?的主要内容,如果未能解决你的问题,请参考以下文章

Vue Storybook 动态故事

Storybook 不支持 vuetify 的 v-calendar

如何在 Storybook 上实时编辑类/功能组件

如何在 Storybook 中注册全局 Vue 组件?

React:如何将 Storybook .stories 放在每个组件的目录中?

用于设置服务器 url 的 Storybook 插件