2.4.2
https://jsbin.com/qejofexedo/edit?html、js、output
複製リンクを参照してください。
Expand is True
をクリックすると、 expand
がfalse
ます。 そして、 countA
変更されました。
Expand is Ture
をクリックしても、何も起こりませんでした。
countA
とcountB
変更されました。
クリックすると、 expand
がfalse
に変更されたと思いますが、すぐにクリックイベントがトリガーされます。 別のvnodeクリックイベントを実行します。 次に、展開をtrue
変更しました。
p
、 section
などの別のタグ名に変更しても、エラーは発生しません。i
タグから親div
タグに移動しても、エラーは発生しません
正常なようです
あなたの再現は意図したとおりに機能しています...
@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>
4つのケースがあります:
block 1
とblock2
でクリックイベントをリッスンし、うまく機能しますelement 1
とelement 2
でリッスンし、うまく機能しますblock 1
とelement 2
でイベントリッスンをクリックし、 expand
をtrueに変更しても問題ありません。 ただし、元に戻すことはできません。element 1
とblock 2
でイベントリッスンをクリックします。 expand
をfalseに変更することはできません。 ただし、 expand
をtrueに変更できます。したがって、これは次の理由で発生します。
<i>
の内部クリックイベントが発生し、nextTick(マイクロタスク)で最初の更新がトリガーされますこれは修正が非常に難しいため、更新キューイングにマイクロタスクを利用する他のライブラリにもこの問題があります(例:Preact)。 Reactは合成イベントシステムを使用しているため(おそらくこのようなエッジケースが原因)、この問題は発生していないようです。
これを回避するには、2つの外側の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>
最も参考になるコメント
したがって、これは次の理由で発生します。
<i>
の内部クリックイベントが発生し、nextTick(マイクロタスク)で最初の更新がトリガーされますこれは修正が非常に難しいため、更新キューイングにマイクロタスクを利用する他のライブラリにもこの問題があります(例:Preact)。 Reactは合成イベントシステムを使用しているため(おそらくこのようなエッジケースが原因)、この問題は発生していないようです。
これを回避するには、2つの外側のdivに異なるキーを指定して、更新中にそれらを強制的に置き換えることができます。 これにより、バブルイベントが取得されなくなります。