Search code examples
vuejs3storybookvue-directives

Storybook + Vue3 - Error when trying to use custom directives


When trying to use custom directives with Vue3 and storybook, I get this error:

Error with Vue3 directive in storybook

I don't understand the issue and have no idea where to even start to look. I'm still very new to Vue and storybook. I created a small test directive just to make sure it wasn't something to do with a more complicated one:

app.directive('red-bg', {
  beforeMount: (element, binding) => {
    element.style.backgroundColor = "red";
  }
});

and applied it: <div class="wmr-select relative" ref="selectRef" v-red-bg>

It works in the normal app part of the the project (as you can see with the red bg): enter image description here

But in story book I get the error in the first image. I haven't been able to find any kind of answer for this.

Hoping someone will swoop in and save me. Thanks.


Solution

  • For Storybook 7+, see P-A Bouly's answer

    Since Storybook is using another file to initialize your app, you need to define the directive in both files.

    This is explained in the configuring storybook section of the doc.

    In my case, I had defined the directive in my main.js file, but I also had to define it in the preview.js file, of the .storybook folder.

    As a reference, here is was my .storybook/preview.js looks like:

    import { app } from "@storybook/vue3";
    /* all the other import needed for my project **/
    import store from "@/store";
    /** ...  */
    
    export const parameters = {
       /** Some parameters specifics to the plugins of storybook. **/
       /** For example, when using themes. **/
    };
    
    /** App specific initialization, ex defining locale  */
    const i18n = createI18n({
      locale: "en",
      fallbackLocale: "en",
      messages: myLocaleMessageLoader()
    });
    
    /** registering directives  */
    app.directive("my-custom-directive", myCustomDirectiveHandler);
    
    app
      .use(i18n)
      .use(store)
      /** all the other `.use` that my app need.*/
    

    Please note the usage of storybook own app in the import.

    After adding the directive in the .storybook/preview.js I was successfully able to use it in my stories.