Vue: @click会触发其他vnode @click事件。

创建于 2017-09-11  ·  4评论  ·  资料来源: vuejs/vue

2.4.2

复制链接

https://jsbin.com/qejofexedo/edit?html,js ,输出

重现步骤

参见复制链接。

期望什么?

当我单击Expand is True ,然后expand变为false 。 仅有countA更改。

实际发生了什么?

当我单击Expand is Ture ,什么都没有发生。
countAcountB更改。
我想当我单击时, expand更改为false ,但是立即触发了click事件。 它执行另一个vnode单击事件。 然后展开更改为true

和更多

  • 如果我将第二个div重命名为另一个标签名称,例如psection ,则不会发生错误。
  • 如果我在第一个div中将点击事件从i标记移至父级div标记,则不会发生任何错误
bug improvement

最有用的评论

因此,发生这种情况是因为:

  • <i>上的内部点击事件触发,触发nextTick的第一次更新(微任务)
  • 在事件冒泡到外部div之前,将处理微任务。 在更新过程中,单击侦听器将添加到外部div。
  • 因为DOM结构相同,所以外部div和内部元素均被重用。
  • 事件最终到达外部div,触发由第一次更新添加的侦听器,进而触发第二次更新。

这在修复中非常棘手,其他利用微任务进行更新排队的库也存在此问题(例如Preact)。 React似乎没有这个问题,因为它们使用了综合事件系统(可能是由于类似这样的极端情况)。

要解决此问题,您只需为两个外部div提供不同的键,以强制在更新过程中将其替换。 这将阻止冒泡的事件被拾取:

<div class="header" v-if="expand" key="1"> // block 1
  <i @click="expand = false, countA++">Expand is True</i> // element 1
</div>
<div class="expand" v-if="!expand" @click="expand = true, countB++" key="2"> // block 2
  <i>Expand is False</i> // element 2
</div>

所有4条评论

qq20170911-185025
看起来很正常

您的生殖器正在按预期工作...

@Kingwl @ yyx990803抱歉。 我测试别人的情况,忘了找回。

重要的代码是

<div class="header" v-if="expand"> // block 1
  <i @click="expand = false, countA++">Expand is True</i> // element 1
</div>
<div class="expand" v-if="!expand" @click="expand = true, countB++"> // block 2
  <i>Expand is False</i> // element 2
</div>

有四种情况:

  • click事件监听block 1block2 ,效果很好
  • click事件监听element 1element 2 ,效果很好
  • 单击事件监听block 1element 2 ,将expand更改为true是可以的。 但是无法改变。
  • click事件监听element 1block 2 ,不能将expand更改为false。 但是可以将expand更改为true。

因此,发生这种情况是因为:

  • <i>上的内部点击事件触发,触发nextTick的第一次更新(微任务)
  • 在事件冒泡到外部div之前,将处理微任务。 在更新过程中,单击侦听器将添加到外部div。
  • 因为DOM结构相同,所以外部div和内部元素均被重用。
  • 事件最终到达外部div,触发由第一次更新添加的侦听器,进而触发第二次更新。

这在修复中非常棘手,其他利用微任务进行更新排队的库也存在此问题(例如Preact)。 React似乎没有这个问题,因为它们使用了综合事件系统(可能是由于类似这样的极端情况)。

要解决此问题,您只需为两个外部div提供不同的键,以强制在更新过程中将其替换。 这将阻止冒泡的事件被拾取:

<div class="header" v-if="expand" key="1"> // block 1
  <i @click="expand = false, countA++">Expand is True</i> // element 1
</div>
<div class="expand" v-if="!expand" @click="expand = true, countB++" key="2"> // block 2
  <i>Expand is False</i> // element 2
</div>
此页面是否有帮助?
0 / 5 - 0 等级

相关问题

robertleeplummerjr picture robertleeplummerjr  ·  3评论

franciscolourenco picture franciscolourenco  ·  3评论

paceband picture paceband  ·  3评论

6pm picture 6pm  ·  3评论

bfis picture bfis  ·  3评论