Vue @keydown on v-dialog/v-overlay stops working when a <v-card> is present

Viewed 939

It seems that the Vue @keydown on v-dialog/v-overlay stops working when a < v-card > is present. Why does this not work, and how to fix?

<v-overlay :value="olyThing" @keydown.esc="olyThing=false" tabindex="0">
    <v-card
        width="80vw"
        height="80vh"
        @click="olyThing=false">
    </v-card>
</v-overlay>

While this does does work:

<v-overlay :value="olyThing" @keydown.esc="olyThing=false" tabindex="0">
</v-overlay>

Somehow the v-card is preventing the keydown to come through. Tried to put the @keydown on the v-card, but this doesn't fix it. Same effect on a v-dialog, instead on a v-overlay. I also tried doing a @keydown.native.esc, but nothing seems to work.

I'm not looking for a solution involving an eventHandler on the window. I'd like to keep this localized to the component.

2 Answers

I have not been able to figure out why the v-card prevents the @keydown to function. But an alternate solution that still is only active on the current page and not global is this:

A complete setup requires three parts.

  1. The method to call when a key is pressed.
  2. Adding the event listener.
  3. Removing the event listener.

You will need the separate method in order to destroy the event listener later:

methods: {
    onKeydown(e) {
        if (this.isOverlay) {
            if (e.keyCode == 37) {
                console.log('LEFT')
            } else if (e.keyCode == 39) {
                console.log('RIGHT')
            }
        }
    },
}

mounted() {
    // Keypresses on overlay:
    document.addEventListener('keydown', this.onKeydown)
},

beforeDestroy() {
    document.removeEventListener('keydown',this.onKeydown)
},

Thanks to Watermelon Sugar for the suggestion.

Try this approach:

mounted() {
    document.addEventListener("keydown", (e) => {
        // If  ESC key was pressed
        if (e.keyCode == 27) {
            this.showdialog=false
            
            // or if you have created a dialog as a custom component, emit an event
            // this.$emit('closeDialog')
        }
    });
},
Related