Отправляйте и прослушивайте события между родительским и дочерним компонентами в Vue.js, чтобы реагировать на ввод с клавиатуры.
Я начинаю изучать Vue.js. Я использовал его пару лет назад, когда он был на подъеме. Профессионально в прошлый раз я сосредоточился на разных вещах, но я планирую использовать Vue.js для будущего проекта, поэтому я снова изучаю мир Vue 2.6.
Вчера мне пришлось создать быструю панель администратора для демонстрации на работе. В качестве основы для своей работы я использовал бесплатную и мощную тему администратора Vuestic.
Цель: мне нужно было реализовать модальное окно, которое показывает некоторый контент и запускается нажатием определенной кнопки на клавиатуре.
Что кажется очень простой задачей, мне пришлось ускорить несколько часов, чтобы наконец решить ее. Я много гуглил, реализовывал разные подходы и все равно потерпел неудачу. Думаю, профессионал Vue решил бы это за считанные минуты, но в какой-то момент я был настолько неистов, что теперь хочу поделиться своей реализацией, чтобы другие могли извлечь из нее уроки, а профессионалы могли дать совет с более элегантными решениями.
Давайте сломаем это….
Первый вопрос: Где поднимать событие?
Реализация события внутри моего дочернего компонента (например, блок в админке) не сработала, так как область нажатия клавиши ограничена. Нужно было сфокусировать блок и нажать горячую клавишу, чтобы вызвать событие. Однако я хотел всегда открывать это модальное окно всякий раз, когда я нажимаю клавишу.
Поэтому я решил поместить его в один из вызовов родительских компонентов AppLayout.vue.
Вот код части экспорта {} в компоненте одного файла:
mounted () { window.addEventListener('keypress', e => { // key m = 109 if (e.keyCode === 109) { this.$root.$emit('hotkey') this.openCallModal = true } }) },
Как видите, событие под названием «горячая клавиша» возникает при нажатии клавиши с кодом 109 (= клавиша «M»). Код ключа можно найти, распечатав его с помощью console.log(e.keyCode).
Крайне важно использовать область $root перед методом $emit. Без этого это не сработает.
Обратите внимание, что здесь я использую лямбда-функцию (или стрелку) с помощью оператора =›. Об этом подробнее здесь".
Второй вопрос: Как прослушать событие в дочернем компоненте?
Почему-то это была самая сложная часть. Я пробовал много разных способов прослушать событие. Я видел, как событие уже запустилось на консоли Vue, но мой дочерний компонент не смог его прослушать.
Итак, вот решение:
export default { name: 'mychildcomponent', data () { return { showModal: false, } }, mounted () { this.$root.$on('hotkey', this.reactToHotkey) }, methods: { reactToHotkey: function (event) { this.showModal = true }, }, }
В методе mounted() я зарегистрировал прослушиватель событий, реализующий обратный вызов reactToHotkey(), который является одним из моих зарегистрированных методов.
С помощью этого метода я могу получить доступ к данным компонента и манипулировать ими. showModal — переменная модели для моих модальных окон. Установка его в true откроет модель.
Вот и все. Оглядываясь назад, я нашел очень простое решение, но мне потребовалось некоторое время, чтобы понять его. Я рад, если это может помочь кому-то, и я рад услышать комментарии.