Vue.js 方法使用 $emit 和 $on 多次调用,而该方法只应调用一次

Vue.js method called multiple times using $emit and $on when it should only be called once

我正在使用总线允许组件通过此 link 中描述的方法与其他组件交互:https://forum.vuejs.org/t/create-event-bus-in-webpack-template/4546/2 .

我有一个在创建的钩子中调用的方法,它使用总线发出事件。

created () {
  this.getReviewDeck()
},
myMethod () {
    bus.$emit('increment')
}

在另一个组件(包含在上述组件中)中,我将事件侦听器附加到创建的挂钩中,如下所示:

created () {
  bus.$on('increment', this.incrementCount)
},
incrementCount () {
  console.log('count incremented')
}

如果我第一次访问该组件,一切正常,控制台将记录 'count incremented' 一次。但是,如果我离开组件然后在下次导航回它时 'count incremented' 将被记录两次,如果我离开并再次返回它现在将被记录三次等

我不太清楚到底发生了什么或如何最好地解决这个问题,所以每次我转到该组件时,消息只记录一次而不是多次。

必须在销毁时删除事件处理程序。

 beforeDestroy () {
    EventBus.$off('increment', this.incrementCount)
 },

你可以使用$.once

created () {
  bus.$once('increment', this.incrementCount)
},

如果您只想在事件发出后执行一次操作,这适用于这种情况。如果您想继续监听一个事件怎么办,例如:如果您将鼠标悬停在图表上的数据点上,您想要触发其他组件的某些操作。 在这种情况下,使用 $once 不起作用。 我面临同样的问题,我在悬停时发出一个事件并使用 $on 订阅它,它应该只被调用一次但在我的情况下它被调用多次。

这就是我发出事件的方式;

this.$eventBus.$emit("SHOW_HOVERLINE", d);

这就是我订阅活动的方式;

this.$eventBus.$on("SHOW_HOVERLINE", this.someFunction);

我遇到了类似的问题,none 上述答案对我有用。 我通过将 eventBus 添加为 Vue 全局实例解决了这个问题

将其添加到 main.js 文件中

Vue.prototype.$bus = new Vue();

并在组件中调用它,例如:

   mounted(){
    this.$bus.$on('chatData', (data) => {
        console.log('receieved in component');
    });
   },
   beforeDestroy() {
    this.$bus.$off('chatData');
   },
   methods:{
    sendData(data){
     this.$bus.$emit('someData',data); 
    }
   }

删除所有监听器:

this.$eventBus.$off()

将此添加到主要组件生命周期的 beforeDestroy() 事件中。

beforeDestroy() {
   this.$bus.$off('chatData');
}

Vue 源代码中似乎发生了一些变化,因为在 destroyed 或 beforeDestroy 或 beforeRouteLeave 或任何其他挂钩中关闭 eventBus 侦听器会执行以下操作 - 旧侦听器与在 created 挂钩中重新注册的新侦听器一起删除。

对于 destroyed 和 beforeDestroy 钩子,这是可以理解的,因为它们是在 created 钩子之后调用的。所以 created() 添加了监听器,而 destroyed() 将它们全部删除,而不仅仅是之前 created() 中的监听器。但是对于路由挂钩我不理解这种行为,因为它们是在 created() 之前调用的,但是所有相同的重新注册的侦听器都不起作用。

我所做的是在重新注册之前关闭创建的钩子中的 eventBus 侦听器

created() {
  eventBus.$off("someListener");
  eventBus.$on("someListener", () => {
    // do smth
  })
}

但这只有在重新创建组件时才有效,它在应用程序生命周期中只创建一次,注册的侦听器将不起作用。但是如果组件创建一次我们就不需要重新注册了。