You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Vue组件Story中触发Storybook暗色模式channel事件

实现方法

先修正preview.js的现有错误

你当前的preview.js存在两个问题导致监听无法生效:

  • 刚执行channel.on绑定监听就立刻调用channel.off解绑,监听逻辑还没等事件触发就被移除
  • channel.off需要传入和channel.on完全相同的函数引用才能正确解绑,你传入了新的匿名函数,既无法解绑原有监听,也没有实际执行意义

修正后的preview.js代码如下:

// .storybook/preview.js
import { addons } from '@storybook/addons';

const channel = addons.getChannel();
const handleDarkModeChange = (isDark) => {
  console.log('暗色模式状态:', isDark ? '激活' : '关闭');
  // 在这里写实际的暗色模式切换逻辑,比如给根节点挂载dark类名
  document.documentElement.classList.toggle('dark', Boolean(isDark));
};
// 绑定事件监听
channel.on('STORYBOOK_DARK_MODE_VUE', handleDarkModeChange);

如果后续需要解绑监听,把handleDarkModeChange作为第二个参数传入channel.off即可,不要在初始化阶段就执行解绑。

修改Story文件,在组件事件回调中主动触发channel事件

Storybook的addon channel是独立的事件总线,组件本身的原生事件、storybook action事件都不会自动转发到channel,你需要在组件的onToggle回调里主动调用channel的emit方法发送事件。
修改后的story代码:

import BToggle from './Toggle.vue';
import { addons } from '@storybook/addons';

export default {
  name: 'Components/Toggle',
  component: BToggle,
  parameters: {
    docs: {
      description: {
        component: 'Nothing to see here',
      },
    },
  },
  argTypes: {
    label: {
      control: { type: 'text' },
    },
    onToggle: {
      action: 'changed',
    },
  },
};

const Template = (args) => ({
  components: { BToggle },
  props: Object.keys(args),
  setup() {
    const channel = addons.getChannel();
    const handleToggle = (toggleValue) => {
      // 保留原有action日志能力,保证actions面板能正常收到事件
      args.onToggle(toggleValue);
      // 向channel发送指定事件,把当前开关的布尔值作为参数传递
      channel.emit('STORYBOOK_DARK_MODE_VUE', toggleValue);
    };
    return { handleToggle };
  },
  template: '<b-toggle v-bind="$props" @onToggle="handleToggle"></b-toggle>',
});

export const Default = Template.bind({});
Default.args = {
  label: 'default',
};

关于两个dark mode插件的差异说明

  • 通用版storybook-dark-mode是跨框架适配的官方插件,内部使用的事件名不是STORYBOOK_DARK_MODE_VUE,而是插件内置常量导出的DARK_MODE_EVENT_NAME,对应值为storybook-dark-mode/toggle
  • 你安装的storybook-dark-mode-vue是Vue生态的适配分支版本,才会使用STORYBOOK_DARK_MODE_VUE作为事件标识,两个插件的事件不要混用
  • 如果你只需要使用Storybook工具栏自带的暗色模式切换按钮,不需要额外在组件内写emit逻辑,插件会自动触发对应事件,你只需要在preview.js的监听回调里写主题切换逻辑即可。上面的emit写法仅适用于你需要通过组件内的开关联动全局暗色模式的场景。

内容的提问来源于stack exchange,提问作者rugbert

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.02 05:15:18