Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Listeners are not cleaned upon component reuse #7749

Closed
luobotang opened this issue Mar 6, 2018 · 7 comments
Closed

Listeners are not cleaned upon component reuse #7749

luobotang opened this issue Mar 6, 2018 · 7 comments

Comments

@luobotang
Copy link

Version

2.5.13

Reproduction link

https://943ccf3255c84eb994ce69d305048954.production.codepen.codes/

Steps to reproduce

<div id="root"></div>
<script src="vue.js"></script>
<script>
var TestCom = {
  template: `<div @click="$emit('test')"><slot /></div>`
}
var vm = new Vue({
  data: {ok: true},
  el: '#root',
  template: `
    <test-com v-if="ok" @test="onclick">OK</test-com>
    <test-com v-else>Not OK</test-com>
  `,
  methods: {
    onclick() {
      console.log('clicked at: '   new Date())
    }
  },
  components: {
    TestCom
  }
})
setTimeout(() => vm.ok = false, 1000)
</script>

What is expected?

1秒后,页面显示“Not OK”,此时点击后应该没有响应

What is actually happening?

显示“Not OK”,点击后打印日志

@luobotang
Copy link
Author

通过跟踪代码执行,发现问题应该是出在:

https://github.com/vuejs/vue/blob/v2.5.13/src/core/instance/lifecycle.js#L260

  if (listeners) {
    const oldListeners = vm.$options._parentListeners
    vm.$options._parentListeners = listeners
    updateComponentListeners(vm, listeners, oldListeners)
  }

由于重新渲染得到的 vnode 中,listeners 为空,这一次不会执行更新 listeners 的操作,所以组件还是保持原有的事件处理,也就是说仍能够响应 test 事件。

相应的,如果出现 bug 的例子修改下:

  template: `
    <test-com v-if="ok" @test="onclick">OK</test-com>
    <test-com v-else @test="onclick2">Not OK</test-com>
  `,

那么组件在点击后会执行 onclick2 方法,这是由于新的 listeners 不为空,可以正确进行更新。

@javoski javoski added the bug label Mar 6, 2018
@HerringtonDarkholme
Copy link
Member

You can add key property to inform Vue to not reuse vnode for now.
https://codepen.io/anon/pen/vdqeGV

@HerringtonDarkholme
Copy link
Member

HerringtonDarkholme commented Mar 6, 2018

Hi @luobotang, while work around exists for this issue, I think listener not being updated is still a bug. Since reusing vnode in this case does work:

<test-com v-if="ok" @test="onclick">OK</test-com>
<test-com v-else @test="onclick2">Not OK</test-com>

If Vue does update listeners in the above case, it should remove listeners as well.

@luobotang
Copy link
Author

@HerringtonDarkholme agree with you ^_^

@luobotang luobotang reopened this Mar 6, 2018
@posva posva added regression and removed bug labels Mar 6, 2018
@posva
Copy link
Member

posva commented Mar 6, 2018

Originally added at #7294

@posva posva changed the title 自定义组件事件未正常解绑 Listeners are not cleaned upon component reuse Mar 6, 2018
@javoski
Copy link
Member

javoski commented Mar 6, 2018

So this bug had been fixed last year, but the new release is not published yet😂.(d8b0838)

@javoski javoski closed this as completed Mar 6, 2018
@posva
Copy link
Member

posva commented Mar 6, 2018

Oh lol, I saw the date and didn't even ask myself the question! 😂

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants