You need to enable JavaScript to run this app. Storybook中通过setup函数使用Vuex并注入自定义store的方法
优惠活动
大模型
产品
解决方案
定价
更多

Storybook中通过setup函数使用Vuex并注入自定义store的方法

核心结论

完全支持为单个Story配置专属自定义Vuex store,无需依赖全局preview.js的注入逻辑,核心原理是利用Vue的provide/inject机制,在Story的装饰器层提供与组件useStore()调用时匹配的注入键对应的store实例即可。

前置注意:注入键必须完全匹配

你在组件中调用useStore()时传的参数,决定了provide时需要使用的键,二者必须完全一致,否则组件无法拿到自定义store:

  • 如果组件写的是无参的useStore():需要从vuex导入内部默认的storeKey作为provide的键
    import { storeKey } from 'vuex'
    
  • 如果组件写的是自定义键的useStore(key)(和你全局app.use(store, key)使用的是同一个自定义key):直接导入项目里导出的这个key作为provide的键即可
    import { key } from '@/store'
    

具体实现方案

方案1:单Story独立配置装饰器

适合仅少量Story需要自定义store的场景,写法如下:

// 组件对应的Story文件,如 src/components/MyComponent.stories.js
import { h, provide } from 'vue'
import { createStore } from 'vuex'
// 按组件实际的useStore调用情况导入对应的键
import { storeKey } from 'vuex' // 无参useStore用这个
// import { key } from '@/store' // 自定义key的useStore用这个
import MyComponent from './MyComponent.vue'

export default {
  title: 'Components/MyComponent',
  component: MyComponent
}

// 默认Story(保留全局preview注入的话,会使用全局store)
export const Default = {}

// 自定义store的专属Story
export const WithCustomStore = {
  // Story本身的props、args正常编写即可,会自动透传
  args: {
    title: '测试标题'
  },
  decorators: [
    (storyFn) => ({
      setup() {
        // 创建完全自定义的store,配置规则和普通Vuex store完全一致
        const customStore = createStore({
          state: () => ({
            // 按需编写组件依赖的state
            userName: 'Story专属测试用户',
            count: 100
          }),
          // 按需补充mutations、actions、getters、modules即可
        })
        // 将自定义store provide给组件,键必须和useStore调用的键完全匹配
        provide(storeKey, customStore) // 对应无参useStore的情况
        // provide(key, customStore) // 对应自定义key的情况
        return {}
      },
      render() {
        // 渲染原Story,自动透传所有args、props配置
        return h(storyFn())
      }
    })
  ]
}

方案2:封装可复用的store注入装饰器

适合多个Story都需要自定义store的场景,避免重复编写逻辑:

  1. 在.storybook目录下编写公共装饰器:
// .storybook/withVuexStore.js
import { h, provide } from 'vue'
import { createStore } from 'vuex'
// 按项目实际情况导入对应的键
import { storeKey } from 'vuex'
// import { key } from '@/store'

/**
 * 自定义store注入装饰器
 * @param {Object} storeConfig 自定义的Vuex store配置
 */
export const withVuexStore = (storeConfig) => (storyFn) => ({
  setup() {
    const customStore = createStore(storeConfig)
    provide(storeKey, customStore) // 替换为你实际使用的注入键
    return {}
  },
  render() {
    // 渲染原Story,完整保留原有args、props配置
    return h(storyFn())
  }
})
  1. 在Story中直接调用该装饰器即可:
export const WithCustomCount = {
  decorators: [
    withVuexStore({
      state: () => ({ count: 999 }),
      // 其他store配置按需编写
    })
  ]
}

常见问题说明

  • 如果你保留了preview.js里的全局app.use(store, key)逻辑,装饰器里provide的store会优先级更高,覆盖全局注入的store,组件会优先拿到自定义store,不会产生冲突。
  • 如果想完全脱离全局注入,可以直接删掉preview.js里的全局store注入代码,所有Story的store都通过装饰器独立配置,完全不会互相污染。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.23 10:45:08