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

时间:2017-01-26 17:52:54

标签: vuejs2 vue-component vue.js

我正在使用总线允许组件通过此链接中描述的方法与其他组件进行交互: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')
}

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

我无法弄清楚究竟发生了什么或者如何最好地解决这个问题,这样每次我去组件时,消息只记录一次而不是多次。

6 个答案:

答案 0 :(得分:23)

必须删除destroy上的事件处理程序。

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

答案 1 :(得分:5)

您可以使用$ .once

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

答案 2 :(得分:4)

似乎就像Vue源代码中的某些更改一样,因为要关闭在destroy或beforeDestroy或beforeRouteLeave或任何其他挂钩中的eventBus侦听器,因此会执行以下操作-删除旧的侦听器,并将新的侦听器重新注册到创建的挂钩中。

对于destroyed和beforeDestroy钩子,在创建钩子之后调用它们是可以理解的。因此created()添加了侦听器,destroyed()删除了所有侦听器,不仅是以前的created()中的监听器。但是对于路由挂钩,我不了解其行为,因为它们在created()之前被调用,但是所有相同的重新注册的侦听器均无法正常工作。

我所做的是先关闭已创建的钩子中的eventBus侦听器,然后再重新注册

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

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

答案 3 :(得分:2)

要删除所有侦听器:

this.$eventBus.$off()

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

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

答案 4 :(得分:1)

如果您只想在事件发出后仅执行一次操作,则此方法有效。如果要继续监听事件,该怎么办,例如:如果将鼠标悬停在图形上的数据点上,则想触发其他组件的某些动作。 在这种情况下,使用$ once不起作用。 我遇到一个同样的问题,即我在悬停上发出一个事件,并使用$ on对其进行了订阅,该事件应该只被调用一次,但是在我的情况下,它被多次调用。

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

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

这是我订阅活动的方式;

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

答案 5 :(得分:0)

我遇到了类似的问题,上述答案都对我没有帮助。 我通过将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); 
    }
   }