Storybook: Vue $root component data access or setup

Created on 17 Apr 2019  路  16Comments  路  Source: storybookjs/storybook

If Vue project's $root component has a reactive variable (in data or computed) f.e. isMobile, so it can be used in app's components as $root.isMobile, then there is no way to define it in config.js or anywhere globally for storybook usage.

It would be nice to have some option to define $root component's data, computed and methods.

Alternative solution that I use now, but it has annoying performance and usability cases:
Add variable as Vue.prototype.isMobile

const localEventBus = new Vue();

Vue.mixin({
    mounted() {
        localEventBus.$on('storybook-rerender', this.storybookForceUpdate);
    },
    beforeDestroy() {
        localEventBus.$off('storybook-rerender', this.storybookForceUpdate);
    },
    methods: {
        storybookForceUpdate() {
            this.$forceUpdate();
        },
    },
});

window.addEventListener('resize', () => {
    localEventBus.$emit('storybook-rerender');
});

Does anyone have alternative solutions? or perhaps there is a way to add data or computed to root component in storybook?

vue inactive question / support

Most helpful comment

Here's a sort of ugly workaround for this. Just add a decorator that wraps every story and manually assign $root in there. Something along the lines of this:

addDecorator({
  i18n,
  beforeCreate: function() {
    this.$root._i18n = this.$i18n;
  },
  template: '<div><slot /></div>',
})

All 16 comments

Hi everyone! Seems like there hasn't been much going on in this issue lately. If there are still questions, comments, or bugs, please feel free to continue the discussion. Unfortunately, we don't have time to get to every issue. We are always open to contributions so please send us a pull request if you would like to help. Inactive issues will be closed after 30 days. Thanks!

Hey there, it's me again! I am going close this issue to help our maintainers focus on the current development roadmap instead. If the issue mentioned is still a concern, please open a new ticket and mention this old one. Cheers and thanks for using Storybook!

@shilman can we reopen this? I have the same question.

Here's a sort of ugly workaround for this. Just add a decorator that wraps every story and manually assign $root in there. Something along the lines of this:

addDecorator({
  i18n,
  beforeCreate: function() {
    this.$root._i18n = this.$i18n;
  },
  template: '<div><slot /></div>',
})

using $root is considered bad practice exactly for this reason, because your component can only be used in an environment (root) you have configuration control over. its better to use provide/inject (in your app, your root comp can provide and in storybook a decorator could provide) or a vuex store

@backbone87 any ideas on how you use provide in a decorator?

Thanks

Sorry @graup , missed your comment back in June. Still an issue?

Hi everyone! Seems like there hasn't been much going on in this issue lately. If there are still questions, comments, or bugs, please feel free to continue the discussion. Unfortunately, we don't have time to get to every issue. We are always open to contributions so please send us a pull request if you would like to help. Inactive issues will be closed after 30 days. Thanks!

@shilman yes, I believe this is still an issue, albeit a low priority one since there are possible (hacky) workarounds. Looks like nobody has a need for this strong enough to whip up a PR.

I have the same issue and when I use this.$root.isMobile in my components for my app and inject those components in storybook which is in another context it doesn't work. @stale I actually have a need for that :)

@graup I tried your workaround by doesn't work for me. Could you please give me info on that with some more code examples ? :) I would appreciate it.

@naimlatifi5 I only tested it with vue-i18n, but I don't have any complete example right now. If you could post a link to a test repo, I can try to take a look there.

Hi @graup,
Yes and please find a code example with storybook here https://github.com/naimlatifi5/storybookwithissueroot . In the root vue instance I have isMobile property with a method that later on component I am referencing as this.$root.methodName and you will see that storybook under Button -> text will generate an error

@naimlatifi5
I cannot offer a fix for the original issue, but if you are interested in a bit more elegant solution of how to use global variables, which also easily works in storybook as well then here is a quick try at that:

  1. Example of how to create global variables. Note that this service does more than it needs for isMobile to work, but I think that is self-sufficient, so it should be easy to try it out. https://gist.github.com/linasmatakas/94a515f78228f023f250a1f959e073b0
  2. main.js:
    2.1. import WindowService from '@/services/window-service';
    2.2. beforeMount() { WindowService.init(); },
  3. Usage in template $screen.isMobile
  4. .storybook/config.js: import and WindowService.init(); anywhere

Hi everyone! Seems like there hasn't been much going on in this issue lately. If there are still questions, comments, or bugs, please feel free to continue the discussion. Unfortunately, we don't have time to get to every issue. We are always open to contributions so please send us a pull request if you would like to help. Inactive issues will be closed after 30 days. Thanks!

Hey there, it's me again! I am going close this issue to help our maintainers focus on the current development roadmap instead. If the issue mentioned is still a concern, please open a new ticket and mention this old one. Cheers and thanks for using Storybook!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

wahengchang picture wahengchang  路  3Comments

shilman picture shilman  路  3Comments

sakulstra picture sakulstra  路  3Comments

tlrobinson picture tlrobinson  路  3Comments

shilman picture shilman  路  3Comments