Vue がインデックスを一意の識別子として使用できない理由の簡単な分析
Sep 23, 2022 pm 08:03 PMvue一意の識別子としてインデックスを使用できないのはなぜですか? Vue が一意の識別子としてインデックスを使用できない理由については、次の記事で紹介していますので、ご参考になれば幸いです。
これには、ネイティブ JS の DOM 操作と仮想 DOM による最適化が含まれます。以下は 2 つの部分に分けて説明します。
- 仮想 DOM
- インデックスをキーとして使用できない理由 [関連する推奨事項: vuejs ビデオ チュートリアル]
1. 仮想 DOM
まず、dom ノードをネイティブに操作する方法を見てみましょう。ただし、ノードの変更によりブラウザは再配置と再描画操作を実行するため、DOM 操作に対するブラウザの応答は非常にエネルギーを消費します (## を参照) #ブラウザ レンダリング ページ プロセス )
nbsp;html> <meta> <meta> <meta> <title>Document</title> <div> <ul></ul> </div> <script> let ul = document.querySelector('ul') for (let i = 0; i < 3; i++) { let li = document.createElement('li') li.innerHTML = i + 1 ul.appendChild(li) } </script>
nbsp;html> <meta> <meta> <meta> <script></script> <title>Document</title> <div> <ul> <item></item> </ul> <button>change</button> </div> <script> new Vue({ el: '#app', data() { return { list: [1, 2, 3] } }, methods: { change() { this.list.reverse() } }, components: { item: { props: ['num'], template: ` <div> {{num}} `, name: 'child' } } }) </script>
#ネイティブ js がこのような操作を行うと必然的に並び替えが発生しますが、ページは部分的に変更されるだけですが、Vue は仮想 dom を導入してから消費電力を大幅に節約できました
それでは? それは仮想 DOM ですか?
vue では、レンダリング関数を実行する前に仮想ノード ツリーを取得し、その仮想ノード ツリーを使用してページをレンダリングできます。ページ dom ノードが動的に変更されると、レンダリング前に、新しく生成された仮想ノードが最後に生成された仮想ノードと比較され、異なる部分のみがレンダリングされます。各仮想ノードはオブジェクトであり、コンテナーのレイヤーの特性を記述します。以下は、vue コードの変更ボタンをクリックする前の仮想ノード ツリーです。vndoe = {
tag: 'ul',
children: [
{ tag: 'li',key:0, children: [{ vnode: { text: '3' } }] },
{ tag: 'li',key:1, children: [{ vnode: { text: '2' } }] },
{ tag: 'li',key:2, children: [{ vnode: { text: '1' } }] }
]
}复制代码
ログイン後にコピー
vndoe = { tag: 'ul', children: [ { tag: 'li',key:0, children: [{ vnode: { text: '3' } }] }, { tag: 'li',key:1, children: [{ vnode: { text: '2' } }] }, { tag: 'li',key:2, children: [{ vnode: { text: '1' } }] } ] }复制代码
変更をクリックすると、新しい仮想ノード ツリーが生成され、それと比較されます
比較後、差分のみが表示されます
では、2 つの仮想ノードの数の差を見つけるにはどうすればよいでしょうか?これには、vue ソース コードの差分アルゴリズムが関係します
#ライフサイクルがマウントされた後、データ ソースが変更される限り、ウォッチャー オブザーバーのコールバックはドライブビューの更新
vm._update(v_rander())_update は、差分アルゴリズムで異なる
key は、差分アルゴリズムを作成するための一意の識別子です。より効率的 比較する必要がある 2 つのノードを正確に見つけます
2. では、なぜインデックスをキーとして使用できないのでしょうか
私たちはまだ前のコードを参照してください。 diff アルゴリズムでは、 key は一意の識別子です。 2 つの仮想ノード ツリーを比較すると、比較のために同じキー値が見つかります。 キー値が同じであることが判明した場合、データは異なります。内部が異なる場合、差分アルゴリズムは変更されたと判断し、再レンダリングします。実際には、位置が変更されただけです。これに一意の識別 ID を追加すると、nbsp;html> <meta> <meta> <meta> <script></script> <title>Document</title> <div> <ul> <item></item> </ul> <button>change</button> </div> <script> new Vue({ el: '#app', data() { return { list: [{ n: 1, id: 0
}, { n: 2, id: 1
}, { n: 3, id: 2
}, ]
}
}, methods: { change() { this.list.reverse()
}
}, components: { item: { props: ['num'], template: `
<div>
{{num}}
`, name: 'child'
}
}
}) </script>复制代码
ログイン後にコピー
nbsp;html> <meta> <meta> <meta> <script></script> <title>Document</title> <div> <ul> <item></item> </ul> <button>change</button> </div> <script> new Vue({ el: '#app', data() { return { list: [{ n: 1, id: 0 }, { n: 2, id: 1 }, { n: 3, id: 2 }, ] } }, methods: { change() { this.list.reverse() } }, components: { item: { props: ['num'], template: ` <div> {{num}} `, name: 'child' } } }) </script>复制代码
[変更] をクリックした後の仮想ノード ツリー
#diff アルゴリズムが比較対象として同じキー値を見つけ、キー値は同じだが内部のデータも同じであることが判明した場合同じように、再レンダリングはされませんが、位置が変更され、ブラウザの消費量が大幅に節約されます。そのため、キーとしてインデックスを使用すると、diff での最適化が失敗します (再利用性が低下し、仮想 Dom の本来の意図に違反します)
nbsp;html> <meta> <meta> <meta> <script></script> <title>Document</title> <div> <ul> <li> <item></item> </li> </ul> <button>del</button> </div> <script> new Vue({ el: '#app', data() { return { list: [1, 2, 3] } }, methods: { del() { this.list.splice(0, 1) } }, components: { item: { template: '<div>{{Math.random()}}' } } }) </script>复制代码
#削除ボタンをクリックした後
データを削除すると、配列の特性により、残りのデータの添字インデックスとキーが -1、つまり 2 番目、3 番目に変更されるため、実際には最後の項目が削除されたことがわかりました。データキーは 1,2 から 0,1 に変更され、diff アルゴリズムはキー 0,1 のデータ内容が変更され、キー 3 の内容が削除されたとみなして、最初と 2 を再レンダリングします。 2番目のデータを削除し、3番目のデータを削除しますが、実際には削除します。最初のコンテンツ、2番目、3番目は変更されたキーの値です。 Vue は、サブコンポーネントのテキスト コンテンツを深く比較しません。オブジェクトの外側の層が変更されたことのみを認識できます。キーを使用して比較します。キーが一意でない場合、仮想 DOM ツリーが誤って操作され、正しくレンダリングされません。 (学習ビデオ共有: Web フロントエンド開発、基本プログラミング ビデオ)
以上がVue がインデックスを一意の識別子として使用できない理由の簡単な分析の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

人気の記事

人気の記事

ホットな記事タグ

メモ帳++7.3.1
使いやすく無料のコードエディター

SublimeText3 中国語版
中国語版、とても使いやすい

ゼンドスタジオ 13.0.1
強力な PHP 統合開発環境

ドリームウィーバー CS6
ビジュアル Web 開発ツール

SublimeText3 Mac版
神レベルのコード編集ソフト(SublimeText3)

ホットトピック











vue3+vite: src に画像を動的にインポートするために require を使用するときのエラーを解決する方法

DefineCustomElement を使用して Vue3 でコンポーネントを定義する方法

Vue3 と Element Plus を使用して自動インポートを実装する方法
