Vue: カスタムディレクティブバインドは、コンポーネントと要素で異なります

作成日 2019年04月15日  ·  6コメント  ·  ソース: vuejs/vue

バージョン

2.6.10

複製リンク

https://jsfiddle.net/bponomarenko/uom10qd2/

再現する手順

  1. ブラウザコンソールを開きます。
  2. トグルボタンを2回クリックします。

何が期待されますか?

ディレクティブは、DOM要素とコンポーネントに適用されたときに(初期化時とボタンをクリックした後に)同じコンソールメッセージを出力します。

何が期待できるのかわかりません。 どちらか

bind: first comp
bind: first elem
unbind: first comp
unbind: first elem
bind: first comp
bind: first elem

または

bind: first comp
bind: first elem
unbind: second comp
unbind: second elem
bind: first comp
bind: first elem

実際に何が起こっているのですか?

ディレクティブからのメッセージはinitでも同じですが、ボタンがクリックされた後は異なります。

実際のコンソール出力:

bind: first comp
bind: first elem
unbind: first comp
unbind: second elem
bind: second comp
bind: first elem

DOM要素とコンポーネントにディレクティブが適用される順序が異なるようです。 私のセットアップでは、構成データを持ついくつかのDOM属性に依存するカスタムディレクティブがあります。 このカスタムディレクティブが「通常のフロー」でバインド/アンバインドされると、すべてが期待どおりに機能します(ディレクティブは要素属性が更新された後にバインドされます)。 ただし、Vueの「インプレースパッチストラテジー」の場合にディレクティブがバインド/アンバインドされると、動作が異なるように見えます。

bug has workaround

最も参考になるコメント

ディレクティブは古いコンポーネントで呼び出されているようですが(再利用されているため)、まだ古い属性があります

回避策として、コンポーネントの1つにキーを設定します

全てのコメント6件

ディレクティブは古いコンポーネントで呼び出されているようですが(再利用されているため)、まだ古い属性があります

回避策として、コンポーネントの1つにキーを設定します

@bponomarenko
@posvaが言ったことは、すでにドキュメントでカバーされています。
これを参考にできます。

https://vuejs.org/v2/guide/conditional.html#Controlling -Reusable-Elements-with-key

@ posva @ pistis回答ありがとうございます。 ええ、それは私たちが最終的に回避策として使用したものです、私はチケットでそれを言及しなければなりませんでした。 ただし、 key属性が存在すると、Vue.jsレンダリングの最適化を使用できなくなります。 それを修正してもらうのは素晴らしいことです。

最適化は、ステートレス要素があることに基づいているため、Vueは、要素を再利用しようとするときに、イベントハンドラーまたはローカル状態を正しく管理する必要がありません。 したがって、これはバグではないと思いますが、ユーザーがこれをより簡単に理解できるように、ドキュメントで改善できる可能性があります。

@Justineo最適化自体の背後にある概念を理解しています。 私の状況では、カスタムディレクティブは、 bind要素にstate属性を追加し、 unbindその属性を削除する役割を果たします。 また、コンポーネントがVue.jsによって再利用されると、ディレクティブは完全に追加/削除されます。 ただし、コンポーネントプロパティの更新とディレクティブの初期化の順序は、コンポーネントの有効期間のさまざまな瞬間で異なるため、カスタムディレクティブの開発は困難です。
実際、これらの最適化手法に関する追加のドキュメントが役立つ場合がありますが、一貫性のないディレクティブのライフサイクルイベントは、私の意見では修正すべきバグです。

回避策として、コンポーネントの1つにキーを設定します

このページは役に立ちましたか?
0 / 5 - 0 評価