vueでv-forを使用する場合、なぜindexをkeyとして使用できないのですか?


結論:
  • DOM更新時にパフォーマンスに問題が発生する
  • ステータスバグ
  • が発生します.
  • Reactのkeyもそうです
  • キーを使用する理由がわかったら、ディレクトリを介して次のセクションに直接ジャンプできます.

  • どうしてkeyを使うの?
    VueとReactは、DOM要素を直接操作せずにデータだけを操作してページを再レンダリングできる仮想DOMを実現しています.背後に隠されている原理は、その効率的なDiffアルゴリズムである.
    VueとReactの仮想DOMのDiffアルゴリズムはほぼ同じであり,その核心は2つの簡単な仮定に基づいている.
  • 同じ2つの構成要素は同様のDOM構造を生成し、異なる構成要素は異なるDOM構造を生成する.
  • 同じレベルのノードのセットで、一意のidで区別できます.

  • 以上の2つの仮定に基づいて,仮想DOMのDiffアルゴリズムの複雑さをO(n^3)からO(n)に低減した.
    1枚の図で簡単に説明します.ページのデータが変化すると、Diffアルゴリズムは同じレベルのノードだけを比較します.
    ノードタイプが異なる場合は、前のノードを直接乾かして、新しいノードを作成して挿入します.
    ノードタイプが同じ場合、ノードのプロパティが再設定され、ノードの更新が実現されます.
    栗を挙げます.
    BとCの間にFを追加することを望んでいます.Diffアルゴリズムはデフォルトでは、CをFに更新し、DをCに更新し、EをDに更新し、最後にEを挿入することで、効率が悪く、性能が不十分です.
    しかし、keyを使用して各ノードに一意の識別を行うと、Diffアルゴリズムはこのノードを正しく識別し、正しい位置領域を見つけて新しいノードを挿入することができます.要するに、keyの役割は主に仮想DOMを効率的に更新するためである.また、vueでは、同じラベル名要素を使用する遷移切り替えにもkey属性が使用されます.これは、vueがそれらを区別できるようにするためです.そうしないと、vueは内部属性を置き換え、遷移効果をトリガーしません.
    ここでは、出力されたDOMコンテンツを巡回するのが非常に簡単でない限り、v-forを使用する場合にkey attributeをできるだけ提供することも推奨される.​
    なぜindexをkeyにできないのですか?
    栗を挙げます.
    const list = [
        {
            id: 1,
            name: "Person1"
        },
        {
            id: 2,
            name: "Person2"
        },
        {
            id: 3,
            name: "Person3"
        },
        {
            id:4,
            name:"Person4"
        }
    ];

    この場合、「Person 4」を削除するのは正常ですが、「Person 2」を削除すると問題が発生します.
    削除前
    key
    id
    index
    name
    0
    1
    0
    Person1
    1
    2
    1
    Person2
    2
    3
    2
    Person3
    3
    4
    3
    Person4
    削除後
    key
    id
    index
    name
    0
    1
    0
    Person1
    1
    3
    1
    Person3
    2
    4
    2
    Person4
    このとき、Person 1以外の残りのPerson 3、Person 4は、対応するkeyとのバインド関係が変化していることが判明したため、再レンダリングされ、パフォーマンスに影響を与える.このときlistitemがselectの選択肢であり、そのうちPerson 3が選択されていた場合、このときPerson 2が削除され、indexをkeyとしてPerson 4が選択されたものとなり、バグが発生する.
    キーとして一意のidを使用すると、Person 2を削除した後、残りの要素はkeyとの関係で変化しないため、再レンダリングされず、パフォーマンスを向上させる目的を達成します.このとき、listitemはselectのオプションとして、上述したバグも現れない.