Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

Max100's avatar

Event listeners in Vue components

This may be a stupid question, but is there a priority of event listeners in a Vue component which contains other components?

I have a component which can include other form components using v-if as well as some modals. I want to listen for certain keypresses and react accordingly.

Is it better to put one main event listener on the parent and then use props to pass that info to the appropriate child (which then need to watch that prop), or is better to listen for the events within the child component elements?

It seems cleaner to listen for keypresses from the child component elements. But some keypresses, like escape, may have different responses, depending on what's happening on the screen at that moment.

Is there a recommended approach?

0 likes
8 replies
LaryAI's avatar
Level 58

When dealing with event listeners in Vue, especially for keypress events, you have a couple of options, and the best approach often depends on the specific requirements of your application. Here's a breakdown of the two approaches you mentioned:

  1. Global Event Listener on Parent Component: You can add a global keypress event listener on the parent component that listens for all keypresses. This can be done by attaching an event listener to the window object or by using Vue's v-on directive at the component level.

    // In your parent component
    mounted() {
      window.addEventListener('keyup', this.handleKeyPress);
    },
    beforeDestroy() {
      window.removeEventListener('keyup', this.handleKeyPress);
    },
    methods: {
      handleKeyPress(event) {
        // Logic to determine which child component should react
        // and possibly emit an event or set a prop accordingly
      }
    }
    

    This approach is useful when you have global shortcuts that should work regardless of which child component is currently focused. However, it can become complex if many conditions determine how the event should be handled.

  2. Local Event Listeners in Child Components: Alternatively, you can add local event listeners within each child component. This keeps the logic for handling the keypresses close to the elements that they affect.

    // In your child component
    methods: {
      handleKeyPress(event) {
        // Handle the keypress event specifically for this component
      }
    }
    

    To listen for keypress events, you can either use the v-on directive on elements within the child component or add a mounted hook similar to the parent component example but scoped to the child component.

    This approach is cleaner when the actions are specific to the child component and do not require knowledge of the parent's state or other children's state.

Recommended Approach:

  • Use local event listeners when the actions are specific to the child component and do not depend on the state of the parent or other children.
  • Use a global event listener on the parent component when you need to coordinate actions between multiple children or when the action is global (like a shortcut that should work regardless of which component is focused).

For keypresses that may have different responses, such as the escape key, you can use a combination of both approaches. For example, you can have a global listener that checks if a modal is open and closes it on escape, and local listeners for other keys that are specific to child components.

Remember to clean up your global event listeners in the beforeDestroy lifecycle hook to prevent memory leaks and unintended behavior.

In summary, there is no one-size-fits-all answer, and the best approach depends on the specific interactions and behaviors you want to implement in your application.

gych's avatar

How much levels deep do you want to check the events in the child components ?

Is it only like:

- parent
 -- child component
 -- child component
 -- child component

or

- parent
 -- child component
  --- child component
 -- child component
 -- child component
  --- child component
Max100's avatar

@gych Thanks for your reply. It's like this:

- parent 
 -- child component
 -- child component
  --- child component
   ---- child component

It started out as just one big unwieldy component, but I decided to try breaking it down into smaller components, which has been a bit of a learning experience :)

gych's avatar

@Max100 Ok and are you using via as separate SPA or with Inertia ?

gych's avatar
gych
Best Answer
Level 29

@Max100 Ok try to use Inertia page props, those are available for the parent and it child components

In Parent component

import { usePage } from "@inertiajs/vue3";

usePage().props.event = "your-event";

In the child component also import usePage and watch usePage().props.event

Max100's avatar

Wow, looks great! Thanks, I'll give it a try!

gych's avatar

@Max100 No problem ! If this solved your issue don't forget to close your thread by selecting the best answer. If you've more questions don't hesitate to reach out :)

Please or to participate in this conversation.