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

dps*_*pst 10 vue.js vue-component vuejs2

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

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

created () {
  this.getReviewDeck()
},
myMethod () {
    bus.$emit('increment')
}
Run Code Online (Sandbox Code Playgroud)

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

created () {
  bus.$on('increment', this.incrementCount)
},
incrementCount () {
  console.log('count incremented')
}
Run Code Online (Sandbox Code Playgroud)

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

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

dps*_*pst 32

不得不在destroy上删除事件处理程序.

 beforeDestroy () {
    EventBus.$off('increment', this.incrementCount)
 },
Run Code Online (Sandbox Code Playgroud)

  • 不知怎的,@ dpst的解决方案在我的情况下效果不好,一旦我将`bus. $ off`添加到`beforeDestory`,它就触发了一次修复.这时我在函数结束时添加了`bus.$ off`并将其称为一天. (3认同)
  • 我认为这个链接上的帖子应该和这个答案一起阅读。这是对重复事件侦听器问题的一个很好的解释(为了更好地理解):https://charlietheprogrammer.com/duplicate-vue-event-listeners-and-how-i-solved-them (2认同)

小智 7

您可以使用$ .once

created () {
  bus.$once('increment', this.incrementCount)
},
Run Code Online (Sandbox Code Playgroud)


Alo*_*nad 5

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

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

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

created() {
  eventBus.$off("someListener");
  eventBus.$on("someListener", () => {
    // do smth
  })
}
Run Code Online (Sandbox Code Playgroud)

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