Отправляйте и прослушивайте события между родительским и дочерним компонентами в 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 откроет модель.

Вот и все. Оглядываясь назад, я нашел очень простое решение, но мне потребовалось некоторое время, чтобы понять его. Я рад, если это может помочь кому-то, и я рад услышать комментарии.