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

如何在Storybook中为Vue组件配置VueRouter的$route参数?

解决Vue组件在Storybook中模拟$route的问题

我正在给一个依赖this.$route.params的Vue组件编写Storybook故事,但不知道如何在Storybook环境中模拟$route对象。尝试用decorators但只会做渲染相关的包裹操作,不知道怎么注入值。找过专门的storybook-router工具,但它多年未维护,语法和新版Storybook不兼容,没法用。

组件里的关键代码:

mounted() {
  axios.get(`.../bla/${this.$route.params.id}.json`)
},

现在Storybook会抛出错误:TypeError: Cannot read properties of undefined (reading 'params')

两种可行的解决方案

不用第三方库,直接通过Storybook的装饰器(Decorators)就能搞定,下面是两种实用方法:

方法1:创建局部VueRouter实例(完整路由模拟)

如果需要完整的路由功能,比如路由跳转等,可以在装饰器里初始化一个VueRouter实例,定义匹配的路由和参数:

import AssetShow from '../app/javascript/src/site/components/assets/Show'
import Vue from 'vue'
import VueRouter from 'vue-router'

Vue.use(VueRouter)

export default {
  title: 'Site/AssetShow',
  component: AssetShow,
};

// 自定义模拟的路由参数
const mockRouteParams = { id: '123' }

export const CustomerSpotlight = () => ({
  components: { AssetShow },
  template: '<AssetShow />',
});

CustomerSpotlight.decorators = [
  () => ({
    // 初始化路由实例,定义匹配当前组件的路由
    router: new VueRouter({
      routes: [
        { path: '/assets/:id', component: AssetShow }
      ]
    }),
    // 用router-view渲染组件,自动注入$route
    template: '<router-view />'
  })
];

方法2:直接注入$route对象(轻量模拟)

如果只是需要$route.params这类基础数据,不需要完整路由功能,可以直接在装饰器里模拟$route并挂载到Vue实例上:

import AssetShow from '../app/javascript/src/site/components/assets/Show'

export default {
  title: 'Site/AssetShow',
  component: AssetShow,
};

export const CustomerSpotlight = () => ({
  components: { AssetShow },
  template: '<AssetShow />',
});

CustomerSpotlight.decorators = [
  (story) => ({
    components: { story },
    data() {
      return {
        // 模拟需要的$route结构
        $route: {
          params: { id: '123' }
        }
      }
    },
    beforeMount() {
      // 将模拟的$route挂载到根实例,让组件能通过this.$route访问
      this.$root.$route = this.$route
    },
    template: '<story />'
  })
];

补充:全局装饰器(多组件复用)

如果多个组件都需要模拟$route,可以在.storybook/preview.js中添加全局装饰器,避免重复代码:

import Vue from 'vue'

export const decorators = [
  (story) => ({
    components: { story },
    data() {
      return {
        $route: { params: { id: 'default-id' } }
      }
    },
    beforeMount() {
      this.$root.$route = this.$route
    },
    template: '<story />'
  })
]

单个故事需要自定义参数时,直接在对应故事的装饰器里覆盖即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 11:15:27