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にできないのですか?
栗を挙げます.
この場合、「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は、対応する
キーとして一意のidを使用すると、Person 2を削除した後、残りの要素は
どうしてkeyを使うの?
VueとReactは、DOM要素を直接操作せずにデータだけを操作してページを再レンダリングできる仮想DOMを実現しています.背後に隠されている原理は、その効率的なDiffアルゴリズムである.
VueとReactの仮想DOMのDiffアルゴリズムはほぼ同じであり,その核心は2つの簡単な仮定に基づいている.
以上の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にできないのですか?
栗を挙げます.
{{item.name}}
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
とのバインド関係が変化していることが判明したため、再レンダリングされ、パフォーマンスに影響を与える.このときlist
のitem
がselectの選択肢であり、そのうちPerson 3が選択されていた場合、このときPerson 2が削除され、indexをkeyとしてPerson 4が選択されたものとなり、バグが発生する.キーとして一意のidを使用すると、Person 2を削除した後、残りの要素は
key
との関係で変化しないため、再レンダリングされず、パフォーマンスを向上させる目的を達成します.このとき、list
のitem
はselectのオプションとして、上述したバグも現れない.