NickMcBurney / storybook-vue3-router

A Storybook decorator that allows you to use Vue 3 / vue-router@4 routing-aware components.
MIT License
29 stars 8 forks source link

why is this router parent component rendered twice? #31

Closed iambumblehead closed 2 years ago

iambumblehead commented 2 years ago

The page components in my storybook app are rendering twice an I'm unable to figure out why. I've scripted a storybook item that reproduces the issue and it is attached below

storybook item ```javascript import vueRouter from 'storybook-vue3-router'; const pagetpl = { template: `
tpl
` } const pagechild = { template: `
child
` } const pageparent = { components: { pagetpl }, template: `
parent
` }; export default { title: 'Page/nestedRouteDemo', component: pageparent }; const Template = () => ({ components: { pageparent }, template: ` `, setup () { return { args: {} }; } }); export const NORMAL = Template.bind({}); NORMAL.decorators = [vueRouter([{ path: '/parent/', name: 'Parent', component: pageparent, children: [{ path: 'child', component: pagechild }] }], { initialRoute: '/parent/child' })]; ```

Storybook renders the parent item twice, but should render the parent once only,

<div>
  tpl
  <div>parent</div>
  <div>
    tpl
    <div>parent</div>
    <div>child</div>
  </div>
</div>

When the app is started normally and these components are rendered using regular vue-router, they are rendered only once, as expected, and the issue occurs in storybook only.

NickMcBurney commented 2 years ago

This is happening because your mounting the router twice, because you use parentpage as the component for your /parent/ route, and in the Template which storybook uses (which is simiar to App.vue in regular vue app).

To fix you can just change:

const Template = () => ({
  components: { pageparent },
  template: `
    <pageparent v-bind="args" />`,
  setup () { return { args: {} }; }
});

to

const Template = () => ({
  template: `<router-view />`
});

Then when const Template is renders it looks at your router setup (passing into vueRouter()) and renders the <pageparent /> component, along with children etc.

I've checked this locally and it renders as expected: image

iambumblehead commented 2 years ago

I see. thank you :)

I haven't had a chance to use this but will let you know how it goes Monday

iambumblehead commented 2 years ago

Monday was a holiday here. This is working thank you.