Vuetify: [Bug Report] When using v-menu item to trigger v-dialog, using click.stop causes menu to stay open

Created on 18 Apr 2019  路  4Comments  路  Source: vuetifyjs/vuetify

Versions and Environment

Vuetify: 1.5.10
Last working version: 1.2.10
Vue: 2.6.10
Browsers: Chrome 71.0.3578.80
OS: Windows 10

Steps to reproduce

Use v-menu with an item (@click.stop handler) that triggers a v-dialog to open.

Expected Behavior

Dialog appears, and menu auto-closes

Actual Behavior

1 - menu remains open when dialog is opened
2 - menu remains open after dialog is closed

When nesting the v-dialog inside v-menu, both 1 and 2 occur.
When v-dialog is outside v-menu the menu, only 1 occurs.

Reproduction Link

https://codesandbox.io/s/j3n1rl8x3w

Other comments

Removing the .stop modifier...

  • when the v-dialog is outside the v-menu, solves the problem
  • when nested inside the dialog, causes the dialog to flash open and close, as noted in documentation

In my application this nesting is happening across a few components, so the codesandbox is a contrived example.This kind of nesting is probably not the best architecture so I'm re-coding my application in any case.

I report this because: it used to work (vuetify 1.2.x); using the .stop modifier is not always working; and the documentation doesn't have anything about how vuetify components can/can't be nested.

VDialog VMenu bug maybe

Most helpful comment

This is simply a shortcoming of mixing nested activators. Not entirely sure on a path forward but it is something I'd like to make better.

All 4 comments

If you want to have a dialog in the menu you can also use setTimeout https://codesandbox.io/s/r448jzw5lm
This has something to do with changes in microtasks in Vue 2.6, not sure if we can do something about it

This is simply a shortcoming of mixing nested activators. Not entirely sure on a path forward but it is something I'd like to make better.

After digging into this, I retract my previous statement. It actually has to do with this:

https://github.com/vuetifyjs/vuetify/blob/400542f0833738bad5c7b8923c11ea91b75ce206/packages/vuetify/src/mixins/dependent/index.ts#L51

When the menu is closed, all of the children that depend on it are closed as well. In this case, dialog is a dependent of menu. If we did not do this, it would cause interaction issues with other components. Imagine a menu in a dialog, or a dialog in a drawer. If either the dialog or the drawer closes, you wouldn't want the existing menu or dialog lingering around.

The only solution for this that I can think of would involve adding a specific prop to enable this and I'm not entirely convinced that it should be added due to the above reasons.

Here is a workaround: https://codepen.io/johnjleider/pen/ZEzJyrQ?editors=1111

This will obviously break nested dependent interactions and I'm not sure how it would fair for your user-case. I'll leave this open for feedback but I don't believe this is a bug.

A little bit annoying issue, but you can wrap it in your own component for reuse. Works same as normal VDialog (using activator slot), additionally it serves close method on default slot. Written in typescript, but can be modified to work with normal JS.

EDIT: Created using: Vue 2.6.10 && Vuetify 2.2.6

<template>
    <VDialog v-model="isShown" v-bind="$attrs" v-on="$listeners">
        <template #activator="{ on }">
            <slot name="activator" v-bind="{ on: getSafeOnHandler(on) }" />
        </template>

        <slot v-bind="{ close }" />
    </VDialog>
</template>

<script lang="ts">
import Vue from 'vue'

export default Vue.extend({
    name: 'BaseInMenuDialog',

    data: () => ({
        isShown: false,
    }),

    methods: {
        // @see: https://github.com/vuetifyjs/vuetify/issues/7021
        getSafeOnHandler({ click }: { click: Function }): { click: Function } {
            return {
                click(event: Event) {
                    return setTimeout(() => click(event), 0)
                },
            }
        },

        close(): void {
            this.isShown = false
        },
    },
})
</script>
Was this page helpful?
0 / 5 - 0 ratings

Related issues

alterhu2020 picture alterhu2020  路  3Comments

Antway picture Antway  路  3Comments

aaronjpitts picture aaronjpitts  路  3Comments

milleraa picture milleraa  路  3Comments

cawa-93 picture cawa-93  路  3Comments