Нажатие клавиши Escape не работает со вторым модальным окном в vuejs

У меня есть таблица с несколькими строками, в каждой строке есть кнопка, при нажатии на кнопку открывается модальное окно, содержащее элемент формы.

После отправки формы открывается второе окно для подтверждения, а первое окно закрывается.

Ниже приведен код моего примера рабочего процесса.

Моя проблема

При нажатии клавиши Escape работает, когда первое окно было открыто, но не может закрыть второе окно, когда оно было открыто.

<template>
    <div>
        <table>
            <tr>
                <td>
                    <button @click="openFormWindow">Open form</button>
                </td>
            </tr>
        </table>
        <modal v-on-escape="hideFirstModal" v-if="isFirstWindowOpen">
            <div>
                <form @submit="submitFormOne">
                    <input type="text">
                    <button type="submit"></button>
                </form>
            </div>
        </modal>
        <modal v-on-escape="hideSecondModal" v-if="isSecondWindowOpen">
            <p>confirmation window</p>
        </modal>
    </div>
</template>

<script>
export default {
    data () {
        return {
            isFirstWindowOpen: false,
            isSecondWindowOpen: false
        }
    }
    methods: {
        openFormWindow () {
            // form window opens 
            this.isFirstWindowOpen = true
        },
        hideFirstModal () {
            this.isFirstWindowOpen = false
        },
        hideSecondModal () {
            this.isSecondWindowOpen = false
        },
        submitFormOne () {
            // submit the details, let the first window close & open the second window.
            this.isFirstWindowOpen = false
            this.isSecondWindowOpen = true
        }
    }
}
</script>

директива vue on-escape

Vue.directive('on-escape', {
    bind (el, binding, vnode) {
        el.customEventKeydown = function (event) {
            // Check if click was outside the el and his childrens
            if (event.keyCode === 27) {
                vnode.context[binding.expression](event)
            }
        }
        document.body.addEventListener("keydown", el.customEventKeydown)
    },
    unbind (el) {
        document.body.removeEventListener("keydown", el.customEventKeydown)
    }
})

person htoniv    schedule 25.02.2021    source источник


Ответы (2)


Используйте key для каждого компонента <modal>, чтобы Vue не использовал повторно узлы DOM:

<modal v-on-escape="hideFirstModal" v-if="isFirstWindowOpen" key="modal1">
<modal v-on-escape="hideSecondModal" v-if="isSecondWindowOpen" key="modal2">

Vue повторно использовал DOM для первого модального окна, когда создавал второе, поэтому второй прослушиватель событий keydown так и не был создан.

Когда элементы добавляются и удаляются из DOM, Vue иногда пытается помочь, повторно используя старые узлы DOM для ускорения рендеринга. Иногда это может иметь нежелательные побочные эффекты. key по существу инструктирует его не делать этого.

person Dan    schedule 25.02.2021
comment
есть некоторые преимущества и недостатки в использовании vue по сравнению с чистым vanilla js, спасибо за вашу помощь, чувак. - person htoniv; 25.02.2021
comment
Только плюсы! :) Повторное использование DOM — это легкое препятствие при создании директив или чего-либо, что манипулирует DOM вручную, при последовательном использовании 2+ одного и того же элемента. Добро пожаловать, приятель - person Dan; 25.02.2021

Похоже, вам не хватает this.isSecondWindowOpen, он не возвращается в вашей функции данных.

person arapl3y    schedule 25.02.2021
comment
ах да, но я забыл добавить - person htoniv; 25.02.2021
comment
я обновил код, пожалуйста, удалите свой ответ - person htoniv; 25.02.2021
comment
Во-первых, вы можете попробовать добавить @keydown.esc="hideFirstModal" и то же самое для второго модального окна и посмотреть, сработает ли это. Во-вторых, попробуйте добавить индекс табуляции к каждому модальному элементу. (например, tabindex=0) - person arapl3y; 25.02.2021
comment
нет, это не работает ни с одним из случаев. - person htoniv; 25.02.2021