javascripteventsvue.jsvuejs2custom-events

Listen to custom event from js code in script tags vue2


I emit custom event from one of great-grandson of my app.vue main component like this:

this.$emit('logged');

And now I want to listen to this event in my app.vue main component but I would rather do it from javascript within <script> tags than from <template>:

<template>
    <div>
        <app-header></app-header>
        <router-view></router-view>
        <app-footer></app-footer>
  </div>
</template>

<script>
    import header from './components/shared/header.vue';
    import footer from './components/shared/footer.vue';

    export default {
        components: {
            'app-header': header,
            'app-footer': footer
        }
    }

// can I listen to custom events somewhere here above?
</script>

Is this possible to listen to custom event from js code in vue 2? I couldn't find such information.


Solution

  • Read Custom Events and Non Parent-Child Communication in the docs.

    Events emitted from a component do not bubble up more than one level, so you won't be able to directly listen for the logged event emitted by a great grandchild component from your main component unless you proxy the event upwards at each level.

    Alternatively you could use an event bus for non parent-child communication (see above link).

    This is how you would listen for an event in code:

    <template>
      <div>
        <my-component ref="mycomp"></my-component>
      </div>
    </template>
    
    <script>
    
    export default {
      mounted() {
        // You need to have a reference to the component you want to listen to
        // which is why I'm using refs here
        this.$refs.mycomp.$on('logged', () => {
          alert('Got logged event');
        });
      }
    }
    
    </script>
    

    But really in the above situation you'd just use v-on. If you are using an event bus, then you need to use $on() and $off() programmatically. I won't explain the event bus pattern because I'm sure it's been widely discussed on SO already.