Karolius
Karolius

Reputation: 581

How listen to all events from one component in VueJS?

Is there a possibility in Vue to deal with incoming events inside one function in a way similar to this?

<template>         
    <component v-on="eventsDistributor(eventName, $event)"/>                                                                 
</template>                                                                   
<script>                                                                      
export default {                                                                      
  props: {
      handlers: Object,
  },
  methods : {                                                                 
      eventsDistributor (name, $event) {                            
          let handler = this.handlers[name]
          if (handler) return handler($event)
      }                                                                       
  }                                                                           
}                                                                             
</script>                                                                     

Upvotes: 18

Views: 15761

Answers (3)

0x0fee
0x0fee

Reputation: 1

Maybe something like the code below. But in the component you want to listening, you need to register all events, like @event="0".
demo

// Component MyButton
<template>
  <div>
    <button @click="$emit('e1', 100)">ClickMe1</button>
    <button @click="$emit('e2', 200)">ClickMe2</button>
  </div>
</template>

// Parent component
<template>
    <my-button ref="btn" 
            @e1="0" @e2="0" 
            @hook:mounted="onMounted(onEvent)" />
</template>
<script>
export default {
  components: { MyButton },
  data() {
    return { event: "" }
  },
  methods: {
    onMounted(listener) {
      const el = this.$refs.btn;
      const lst = { ...el.$listeners };
      delete lst["hook:mounted"];

      Object.keys(lst).forEach((name) => {
        el.$off(name);
        el.$on(name, (e) => listener(name, e));
      });
    },
    onEvent(...args) {
      console.log(...args);
      this.event = args;
    }
  }
}
</script>

Upvotes: 0

tony19
tony19

Reputation: 138266

I think $listeners might be what you need. It's an object that contains all parent listeners, and it could be forwarded to children with v-on="$listeners".

For example, you have a <button> wrapper component, and you want any listeners on the wrapper to be bound to the button:

<!-- MyButtonWrapper.vue -->
<template>
  <button v-on="$listeners">Click</button>
</template>

<!-- Parent.vue -->
<template>
  <!-- click and mouseover listeners are bound to inner button -->
  <MyButtonWrapper @click="onClick" @mouseover="@mouseover" />
</template>

demo

Upvotes: 31

Radu Diță
Radu Diță

Reputation: 14171

There is no standard way of achieving this.

The author of vuejs offers a hack to listen on all events here. He also explains that introducing regexp or other means of listening to more events will have a performance impact and will probably not do it.

Upvotes: 3

Related Questions