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 ストアド プロシージャで一時テーブルを読み取る

推薦する

MySql 組み込み関数の自習知識ポイントまとめ

文字列関数文字ascii(str)のASCIIコード値をチェックし、strが空の文字列の場合は0を返...

Mysql GTID Mha 設定方法

Gtid + Mha + Binlog サーバー構成: 1: テスト環境OS: CentOS 6.5...

MySQLでの少し複雑な使用例コード

序文MySQL の構文は誰にとっても難しいものではないと思いますが、この記事では主に MySQL の...

VMware Workstation 14 Pro のインストールとアクティベーションのグラフィック チュートリアル

この記事では、VMware Workstation 14 Proのインストールとアクティベーションに...

Windows 7 64 ビットに最新バージョンの MySQL サーバーをインストールする方法のグラフィック チュートリアル

最近、MySQL データベースを勉強していて、設定ファイルを頻繁に変更したため、MySQL データベ...

HTML テーブル マークアップ チュートリアル (9): セル間隔属性 CELLSPACING

テーブルがコンパクトになりすぎないように、テーブル内のセル間に一定の距離を設定できます。基本的な構文...

Dockerでk8sをデプロイする方法

K8s k8s はクラスターです。クラスターには複数の名前空間があります。名前空間の下には複数のポッ...

MySQL の垂直テーブルを水平テーブルに変換する方法と最適化のチュートリアル

1. 縦型テーブルと横型テーブル垂直テーブル: テーブル内のフィールドとフィールド値はキーと値の形式...

DockerコンテナにNFS共有ディレクトリをマウントする実装

以前、https://www.jb51.net/article/205922.htm で、Docke...

VirtualBoxにOpenSuseをインストールする方法

仮想マシンはホストマシンにインストールされます。 CPU とメモリはホスト マシンと共有する必要があ...

IDEA で mysql8.0.3 と mybatis-generator を使用する際に発生するバグ

1. プラグインを追加し、pomファイルの下に次の設定を追加します。 <!-- mybatis...

MySQL 匿名ログインでデータベースを作成できない問題の解決方法

よくある質問ユーザー ''@'localhost' によるデータベー...

MySQLクエリ書き換えプラグインの使用

クエリ書き換えプラグインMySQL 5.7.6 以降、MySQL Server は、サーバーが実行す...

MySQLのインストール時に発生する可能性のある問題

質問1:インストール中に net start mysql と入力すると、次のエラー メッセージが表示...

ブラウザの自動フォーム入力によるウェブページのスタイル損失の原因の分析と解決

バックエンドからフロントエンドまで、なんと悲劇なのでしょう。他の人の CSS を自分の jsp We...