Vueにおけるキーの役割と原理の詳細な説明

Vueにおけるキーの役割と原理の詳細な説明

1. 結論から始めましょう

  • Vue のキーは DOM オブジェクトの識別子です。
  • リストを表示する場合、デフォルトのキーはインデックスです。
  • データが表示のみに使用される場合は、インデックスをキーとして使用しても問題ありません。
  • インデックスをキーとして使用し、後続の操作で順序が破壊されると、確実に効率の問題が発生し、深刻な場合には、誤った DOM がレンダリングされます。

キーの役割と実装原則については、一つずつ説明していきましょう。

2. キーの役割

key は Vue で使用される識別子です。具体的には、キーは Vue 内の仮想 DOM で使用され、実際の DOM には表示されません。

2.1 例

人事情報をリスト形式でまとめて表示します。

<!DOCTYPE html>
<html lang="ja">
<ヘッド>
    <メタ文字セット="UTF-8">
    <title>キーの原理</title>

    <!--vue を導入する-->
    <script type="text/javascript" src="../js/vue.js"></script>
    
</head>
<div id="ルート">
    <h2>スタッフリスト</h2>
    <ul>
        <li v-for="(p,index) 人">
            {{p.name}}-{{p.age}}
        </li>
    </ul>
</div>
<本文>
    <script type="text/javascript">
        定数vm = 新しいVue({
            el:'#root',
            データ:{
                人数:
                    {'id':'001', 'name':'张三', 'age':'18'},
                    {'id':'002', 'name':'李思', 'age':'19'},
                    {'id':'003', 'name':'王武', 'age':'20'}
                ]
            }
        })
    </スクリプト>
</本文>
</html>

この HTML ファイルは、以下に示すようにブラウザで開きます。

画像-20211011224230413

上記のサンプル HTML ファイルではキーを使用していないため、問題はないようです。もちろん、キーを書き込まずにデータを表示するだけでも問題ありません。

上記の例にキーを追加してみましょう。ここでは、各データの ID がキーとして使用されます。

<li v-for="(p,index) 人" :key="p.id">
    {{p.name}}-{{p.age}}
</li>

キーを追加した後の表示結果は、上の画像の結果とまったく同じです。

画像-20211011224928540

ブラウザで要素を表示すると、キーは表示されません。

画像-20211011225246624

これまでのところ、2つの結論を導き出すことができます。1. これはデータの表示にのみ使用され、キーを書き込まなくても効果はありません。2. キーは実際のDOMには表示されません。

実際、キーを書かなくても、Vueは実際のDOMを生成するときにキーを使用します。デフォルトはデータインデックス(インデックス)です。

キーをインデックスに置き換えても、表示されるデータは変わりません。

<li v-for="(p,index) 人" :key="index">
	{{p.name}}-{{p.age}}
</li>

2.2 上記の例を修正する

人事情報に基づいたインデックスを表示し、ヘッダーに人事情報を追加するボタンを追加します

上記の HTML ファイルを少し変更します。

<!DOCTYPE html>
<html lang="ja">
<ヘッド>
    <メタ文字セット="UTF-8">
    <title>キーの原理</title>

    <!--vue を導入する-->
    <script type="text/javascript" src="../js/vue.js"></script>
    <link rel="icon" href="../favicon.ico" type="image/x-icon" />

</head>
<div id="ルート">
    <h2>スタッフリスト</h2>
    <button @click="add">ラオ・リューを追加</button>
    <ul>
        <li v-for="(p,index) 人" :key="index">
            {{p.name}}-{{p.age}}-{{index}}
        </li>
    </ul>
</div>
<本文>
    <script type="text/javascript">
        定数vm = 新しいVue({
            el:'#root',
            データ:{
                人数:
                    {'id':'001', 'name':'张三', 'age':'18'},
                    {'id':'002', 'name':'李思', 'age':'19'},
                    {'id':'003', 'name':'王武', 'age':'20'}
                ]
            },
            方法:{
                追加(){
                    const p = {'id':'004', 'name':'老刘', 'age':'40'}
                    this.persons.unshift(p)
                }
            }
        })
    </スクリプト>
</本文>
</html>

張三、李四、王武のインデックスはそれぞれ 0、1、2 であることがわかります。

画像-20211011230442273

ボタンをクリックして、新しい文字を追加します。この時点でインデックスが変更されます。新しく追加された文字「Lao Liu」はインデックス 0 になります。正しいように見えますが、間違っています。

画像-20211011230815984

もちろん、単にインデックスについて議論するだけでは何も問題はありません。何が間違っているのかを説明するために、新しい例を挙げてみましょう。

2.3 例を再度修正する

インデックスを表示する代わりに、入力ボックスを表示します。各人の姓をその背後の入力ボックスに入力し、新しいデータが挿入された後の元のデータの変化を観察します。

HTMLを少し修正する

<li v-for="(p,index) 人" :key="index">
    {{p.name}}-{{p.age}}
    <入力タイプ="テキスト">
</li>

実際の効果は以下の通り

画像-20211011231349758

この時点では何も問題はなさそうです。次は奇跡を目撃する瞬間です。

Lao Liu を追加したとき、予想とは異なる問題が発生しました。

画像-20211011231548484

これはキーがインデックスの場合であり、データの一意の識別子に変更すれば、このような問題は発生しません。

<li v-for="(p,index) 人" :key="p.id">
    {{p.name}}-{{p.age}}
    <入力タイプ="テキスト">
</li>

ねえ、これが私たちが望んでいるものよ。

画像-20211011231848647

リストに入力がある場合、後続の操作により元の順序が破壊され、DOMエラーが発生します。

3. キーの実装原則

key の実装原理を説明するには、Vue の非常に重要な概念である [仮想 DOM] を紹介する必要があります。

一連のデータが与えられた場合、Vue はこのデータをページ上にレンダリングする必要があります。まず、[仮想 DOM] を生成し、次に [仮想 DOM] に基づいて [実際の DOM] を生成する必要があります。データが変更されると、Vue は [新しい仮想 DOM] を生成します。この [新しい仮想 DOM] は [新しい実際の DOM] を直接生成しないことに注意してください。そうしないと、仮想 DOM は役に立たなくなります。 Vue が行うことは、新しいデータに基づいて生成された [新しい仮想 DOM] と以前の [実際の DOM] を比較することです。同じ場合は、そのまま使用できます (「そのまま取得する」)。異なる場合は、新しい DOM オブジェクトが生成されます。

このプロセスでは、キーが非常に重要な役割を果たします。

最後の例に基づいて分析してみましょう。

1. キーがインデックスの場合。

データを元に[実DOM]を生成するプロセスは以下のようになります。(下図の実DOMの入力ボックスの内容はページ生成後に手動で追加したものであることに注意してください)

ここに画像の説明を挿入

次に、「Lao Liu」という文字を追加して、新しいデータセットを取得します。

ここに画像の説明を挿入

Vueは新しいデータを取得して[新しい仮想DOM]を生成します

ここに画像の説明を挿入

実際のDOMを生成する際には、新しく生成された仮想DOMと元の実際のDOMを比較する必要があります(1つずつ分析します)

ここに画像の説明を挿入

最初のものと比較すると、キーは 0 で、古い DOM 内のキー 0 のデータが検出されました。「Lao Liu-40」と「Zhang San-18」は異なることがわかり、新しいデータ「Lao Liu-40」がページにレンダリングされます。その後、同じ入力ボックスであることがわかりました。そのため、再レンダリングする必要はなく、元の実際の DOM のコンテンツをそのまま使用できます。最初のコンテンツが表示され、この入力ボックスには張三の姓も含まれています。

ここに画像の説明を挿入

2番目と比較すると、キーは1で、古いDOMでキー1のデータを見つけました。「張三-18」と「李思-19」は異なっていることがわかりました。新しいデータ「張三-18」がページにレンダリングされました。後で、同じ入力ボックスであることがわかりました。そのため、再レンダリングする必要はなく、元の実際のDOMの内容をそのまま使用できます。 2番目のコンテンツが表示され、この入力ボックスにもLi Siの姓が含まれていました。

ここに画像の説明を挿入

以降も同様です。

このプロセスを振り返ると、鍵となるのは仮想 DOM 内のオブジェクトの一意の識別子であり、これがデータの「識別情報」を識別します。Vue は、この「識別識別子」に基づいて仮想 DOM 内のコンテンツを比較します。設計の本来の意図は、リソースの費用を節約し、重複部分のレンダリングを回避することです。この例では、効率の問題が発生するだけでなく、誤った DOM がレンダリングされ、非常に深刻な結果が生じます。

2. キーが id の場合。

「Lao Liu」を追加した後、古いDOMと新しいDOMの比較を直接入力します。

ここに画像の説明を挿入

最初のものと比較すると、キーは「004」であり、古いDOMには存在しないことが判明したため、「老刘-40」と新しい入力ボックスが直接生成されました。

2番目と比較すると、キーは「001」であり、古いDOM内のキー「001」のデータは同じであることが判明したため、「張三-18」と入力ボックスが直接使用されます。

最後に、正しい DOM が生成され、リソースの費用が節約されます。

要約する

ID、ID 番号、携帯電話番号など、データの一意の識別子をキーとして使用することをお勧めします。通常、このデータはバックエンドによって提供されます。

後続の操作によって元のデータの順序が崩れない場合は、インデックスをキーとして使用しても問題はありません。

この記事はこれで終わりです。皆さんのお役に立てれば幸いです。また、123WORDPRESS.COM のその他のコンテンツにも注目していただければ幸いです。

以下もご興味があるかもしれません:
  • Vue リストレンダリングでキーが果たす役割の詳細な説明
  • Vue3におけるキーの役割と動作原理についての簡単な説明
  • Vueリストレンダリングキーの原理と機能の詳細な説明

<<:  HTML マークアップ言語 - リファレンス

>>:  カーソル ループを使用して、MySQL ストアド プロシージャで一時テーブルを読み取る

推薦する

Javascriptの基礎を学ぶための10の重要な質問

目次1. Javascript とは何ですか? 2. DOMとは何か3. JSコードの実行方法4. ...

シンプルなドラッグ効果を実現するJavaScript

この記事では、簡単なドラッグ効果を実現するためのJavaScriptの具体的なコードを参考までに紹介...

RR および RC 分離レベルでのインデックスとロックのテスト スクリプトのサンプル コード

基本概念現在の読み取りとスナップショットの読み取りMVCC では、読み取り操作はスナップショット読み...

MySQL の列から行への変換と年月グループ化の例

以下のように表示されます。 SELECT count(DISTINCT(a.rect_id)) zc...

MySQLワームレプリケーションの基本知識

ワームは、その名前が示すように、自ら複製し、その数は倍増、つまり指数関数的に増加します。 MySQL...

Sublime TextがUbuntuで中国語を入力できない問題の最も簡単な解決策

崇高なSublime Text はコード エディター (Sublime Text2 は有料ソフトウェ...

Vue+js はビデオのフェードインとフェードアウト効果を実現します

Vue+jsはビデオのフェードインとフェードアウトを実現します。参考までに、具体的な内容は次のとおり...

nginx プロキシ ポート 80 からポート 443 への実装

nginx.conf設定ファイルは次のとおりです。 ユーザー nginx; ワーカープロセス 1; ...

Vue+element ui はアンカーの配置を実現します

この記事では、アンカー配置を実現するためのVue +要素UIの具体的なコードを例として紹介します。具...

Windows での MySQL 5.7.18 インストール チュートリアル

この記事では、圧縮パッケージから MySQL をインストールする方法について説明します。 1. My...

Vueキャッシュ機能の使い方

目次vue2のキャッシュ機能Vue キャッシュ関数の変換最適化要約するvue2のキャッシュ機能vue...

Linux システム修復モード (シングル ユーザー モード)

目次序文1. シングルユーザーモードでの一般的なバグ修正2. シングルユーザーモードでシステムパスワ...

Docker を使用して Spring Boot をデプロイする方法の例

ここでは主に、スタンドアロンのプログラムを生成できるspring-bootと、Mavenプラグインd...

ブラウザタブの左端に表示されるウェブサイトのアイコンを設定します

この文の目的は何ですか?コードをコピーコードは次のとおりです。 <link rel="...

Vueはシンプルなショッピングカートの例を実装します

この記事では、Vueの具体的なコードを共有して、簡単なショッピングカートを実装します。具体的な内容は...