ホームページ >ウェブフロントエンド >Vue.js >Vue がインデックスを一意の識別子として使用できない理由の簡単な分析
vue一意の識別子としてインデックスを使用できないのはなぜですか? Vue が一意の識別子としてインデックスを使用できない理由については、次の記事で紹介していますので、ご参考になれば幸いです。
これには、ネイティブ JS の DOM 操作と仮想 DOM による最適化が含まれます。以下は 2 つの部分に分けて説明します。
まず、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>また、多くの JS コードは要素を動的に変更してブラウザの再配置を引き起こしており、エネルギー消費が想像できます。一部のノードが変更された場合、それらの変更されたノードをローカルに再配置すると、パフォーマンスが大幅に節約されるのではないでしょうか? ? ? vue が導入した仮想 dom はこの方式を採用しており、以下は vue のコードです
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 ですか?
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 は、差分アルゴリズムで異なる
_patch_ 開始を見つけるために、_patch_ に vnode を生成します。
key は、差分アルゴリズムを作成するための一意の識別子です。より効率的 比較する必要がある 2 つのノードを正確に見つけます
2. では、なぜインデックスをキーとして使用できないのでしょうか
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> <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 サイトの他の関連記事を参照してください。