Storybook: 6.0 Vue doesn't support dynamic $emit

Created on 6 Aug 2020  路  4Comments  路  Source: storybookjs/storybook

This code won't work, SB 6.0 can't detect the events:

this.$emit(this.shouldDisable ? 'onClickWhenDisabled' : 'onClick', event);

However, this will work:

if (this.shouldDisable) {
  this.$emit('onClickWhenDisabled', event);
} else {
  this.$emit('onClick', event);
}
vue help wanted question / support

All 4 comments

What doesn't it support exactly? The code doesn't work or .... ?

Hello @rockmandash

vue-docgen-api is under the hood of storybook.
It detects only static events. But you can tell it litterally what each event is going to fire.

Use @fires like this:
https://github.com/vue-styleguidist/vue-styleguidist/blob/df1c6061a80730a130e3fc0a0fc52e41bae11fbc/packages/vue-docgen-api/src/script-handlers/__tests__/eventHandler.ts#L212-L233

It is not documented yet but I know I should.

Tell me if it helps.

Basically, where the method that calls your event is defined, you can comment like follows

export default {
    methods: {
        /** 
         * Define the event just before the function block
         *
         * @event onClickWhenDisabled
         * @property { String } prop1 - first prop given by the event
         */
            /** 
         * Define another event just before the function block
         *
         * @event onClick
         * @property { String } p2 - first prop given by the onClick event
         */
        /** 
         * Some comment for the function
         * @fires onClick
         * @fires onClickWhenDisabled
         * @arg { String } name updated property name
         * @arg newValue new value that we want to update
         */
        onUpdate (name, newValue) {
            // some external method, for example from a method
            // (bind to the Vue instance) provided by a standard js class
        }
    }   
}

It is a little crazy verbose, but works. If you are trying to get the controls of storybook to work you also have the possibility to customize them after the fact.

I would really go for the simple approach though:

if (this.shouldDisable) {
  this.$emit('onClickWhenDisabled', event);
} else {
  this.$emit('onClick', event);
}

or, simpler, pass the status in the payload:

this.$emit('onClick', event, his.shouldDisable);

@elevatebart Thank you!
Explicitly describe which event will be emitted solved the problem.

@shilman Sorry I didn't describe my problem clearly, I'll be careful next time!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

tirli picture tirli  路  3Comments

purplecones picture purplecones  路  3Comments

shilman picture shilman  路  3Comments

wahengchang picture wahengchang  路  3Comments

zvictor picture zvictor  路  3Comments