简体   繁体   English

如何监听 VueJS 中的所有自定义事件?

[英]How to listen to all custom events in VueJS?

In my VueJS app I have a Vue instance which I'm using as an event bus for sending data between components.在我的 VueJS 应用程序中,我有一个 Vue 实例,我将其用作在组件之间发送数据的事件总线。

It's just this:就是这样:

import Vue from 'vue';
export const EventBus = new Vue();

Then in my components I import EventBus and use EventBus.$emit() and EventBus.$on() .然后在我的组件中导入 EventBus 并使用EventBus.$emit()EventBus.$on()

This approach is explained here: https://alligator.io/vuejs/global-event-bus/这种方法在这里解释: https : //alligator.io/vuejs/global-event-bus/

What I'd like to be able to do is listen to any event that is sent through EventBus.我希望能够做的是侦听通过 EventBus 发送的任何事件。 If I could bind one listener to all events I could use this for logging or to feed data into some system for my development environment that would show me all data as it went into eventBus, which would be super useful.如果我可以将一个侦听器绑定到所有事件,我可以使用它来记录日志或将数据馈送到我的开发环境的某个系统中,该系统会在进入 eventBus 时向我显示所有数据,这将非常有用。

Is there any type of vm.$listenToEverything() that I'm missing or some way to make this work?有没有我遗漏的任何类型的vm.$listenToEverything()或某种方法来使这项工作?

If you're in an ES6 context, you could take either of below approaches.如果您处于 ES6 环境中,则可以采用以下任一方法。 I explain through comments.我通过评论来解释。

Override through inheritance通过继承覆盖

'use strict'

import Vue from 'vue'

export class EventBus extends Vue {
  // Register a custom callback as meddler that gets called upon each event emission.
  // It can be bound to $on as well. 
  $meddle (callback) {
    this.meddler = callback
  }

  // Override Vue's $emit to call the custom meddler callback upon each event emission.
  $emit (event, ...args) {
    if (this.meddler && typeof this.meddler.call === 'function') {
      this.meddler(event, ...args)
    }

    return super.$emit(event, ...args)
  }

  // We can also override $on() to listen to callbacks being registered.
}

export default new EventBus()

Override through hijacking通过劫持覆盖

Or using a "hijacking" factory class in case you don't want your Vue event bus to be wrapped.或者使用“劫持”工厂类,以防您不希望包装 Vue 事件总线。 The logic is basically the same, however, in this approach we hijack , or in other words, monkey patch the methods instead of overriding them directly.逻辑基本相同,但是,在这种方法中,我们劫持,或者换句话说,猴子修补方法而不是直接覆盖它们。

'use strict'

import Vue from 'vue'

class EventBusFactory {
  static create () {
    return this.hijack(new Vue())
  }

  static hijack (bus) {
    bus.$meddle = callback => {
      bus.meddler = callback
    }

    const orig$emit = bus.$emit
    bus.$emit = (event, ...args) => {
      if (bus.meddler && typeof bus.meddler.call === 'function') {
        bus.meddler(event, ...args)
      }

      orig$emit.call(bus, event, ...args)
    }

    return bus
  }
}

export default EventBusFactory.create()

The author of VueJS provided a hacky solution for listening to all events : VueJS 的作者提供了一个 用于监听所有事件hacky 解决方案

var oldEmit = this.compiler.emitter.emit
this.compiler.emitter.emit = function () {
    console.log('got event: ' + arguments[0])
    oldEmit.apply(this, arguments)
}

Another solution (which is said to also work on v1.0):另一个解决方案(据说也适用于 v1.0):

const old_on = this.$on;
this.$on = (...args) => {
  // custom logic here like pushing to a callback array or something
  old_on.apply(this, args);
};

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM