Vue のキーの機能と原理

目次

導入

鍵の役割

キーの値

キー属性をバインドしないでください

キー値はインデックスです

キー値はデータを一意に識別します

要約する


導入

Vue を使用したことがある場合は、v-for ディレクティブについてよく知っている必要があります。この命令は通常、配列データを走査するために使用されます。v-for コマンドを使用する場合、key 属性は分離不可能である必要があります。この属性とその機能を理解していますか? 価値とは何ですか? 違いはなんですか?この記事ではVueのキーの機能や原理について詳しく紹介していきます!

鍵の役割

キー属性をリストにバインドすると、その属性は仮想 DOM に存在します。キーは仮想 DOM オブジェクトの識別子です。データが変更されると、Vue はユーザーが変更した新しいデータに従って新しい属性を生成します。 . 仮想 DOM。次に、Vue は新しい仮想 DOM と古い仮想 DOM の違いを比較します。比較プロセスは 2 つのケースに分けられます。

新しい仮想 DOM と同じキーが古い仮想 DOM で見つかった場合、仮想 DOM の内容が変更されていない場合は、以前の実 DOM が直接使用されます。仮想 DOM 内のコンテンツが変更されると、新しい実 DOM が生成され、ページ内の以前の実 DOM が置き換えられます。

新しい仮想 DOM と同じキーが古い仮想 DOM に見つからない場合、新しい実際の DOM が作成され、ページにレンダリングされます。

少し混乱していますが、心配しないでください。次の例で詳細な例を示します。

キーの値

キーには主に次の 3 つの状況がありますが、ここでは小さなケースを取り上げて、次の方法をそれぞれ使用して、具体的な効果と違いを確認してみましょう。

ページ上に人のリストを表示し、ボタンを追加します。ボタンをクリックすると、人のリストの前に新しいメンバーが追加されます。(なぜリストの前に置く必要があるのでしょうか。これは重要なポイントです。)

キー属性をバインドしないでください

v-for を作成したときに key 属性を追加しなかった場合、必要な効果には影響しませんでした。対応する実装コードと効果図は以下のとおりです。

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8" />
        <title>key的原理</title>
        <script type="text/javascript" src="../js/vue.js"></script>
    </head>
    <body>
        <!-- 准备好一个容器-->
        <div id="root">
            <h2>人员列表</h2>
            <button @click.once="add">添加一个老刘</button>
            <ul>
                <li v-for="p of persons">
                    {
   
   {p.name}}-{
   
   {p.age}}
                </li>
            </ul>
        </div>
​
        <script type="text/javascript">
            new Vue({
                el:'#root',
                data:{
                    persons:[
                        {id:'001',name:'张三',age:18},
                        {id:'002',name:'李四',age:19},
                        {id:'003',name:'王五',age:20}
                    ]
                },
                methods: {
                    add(){
                        const p = {id:'004',name:'老刘',age:40}
                        this.persons.unshift(p)
                    }
                },
            })
        </script>
</html>

このとき、key属性を書かなくても期待通りの効果が正常に表示されるのではないかと疑問に思う学生もいるかもしれません。では、なぜそんなに面倒なのか、キー属性を追加してみましょう。実際、キー属性を追加しない場合、システムはデフォルトでバインドされたキー属性の値をインデックスに設定します。リストのインデックス (例: {id:'001',name:'Zhang San',age:18}) のインデックス値は 0、{id:'002',name:'Li Si',age: 19 } のインデックス値は 1 などです。各 li タグを識別するため。

キー値はインデックスです

key 属性を追加し、その属性の値をインデックスに指定すると、それによって達成される具体的な効果は、key 属性を追加しない場合と同じです。ただし、具体的な実装コードは少し異なります。

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8" />
        <title>key的原理</title>
        <script type="text/javascript" src="../js/vue.js"></script>
    </head>
    <body>
        <!-- 准备好一个容器-->
        <div id="root">
            <h2>人员列表</h2>
            <button @click.once="add">添加一个老刘</button>
            <ul>
                <!-- 绑定了key属性,并将其值指向于index -->
                <li v-for="(p,index) of persons" :key="index">
                    {
   
   {p.name}}-{
   
   {p.age}}
                </li>
            </ul>
        </div>
​
        <script type="text/javascript">
            Vue.config.productionTip = false
            new Vue({
                el:'#root',
                data:{
                    persons:[
                        {id:'001',name:'张三',age:18},
                        {id:'002',name:'李四',age:19},
                        {id:'003',name:'王五',age:20}
                    ]
                },
                methods: {
                    add(){
                        const p = {id:'004',name:'老刘',age:40}
                        this.persons.unshift(p)
                    }
                },
            })
        </script>
</html>

対応する実装は上記と同様であり、正しくエフェクトが表示されます。この種の書き込みも比較的一般的です。これには問題はありませんでした。しかし、ここで各リストの後に入力ボックスを追加するとどうなるでしょうか?

 <div id="root">
            <h2>人员列表</h2>
            <button @click.once="add">添加一个老刘</button>
            <ul>
                <!-- 绑定了key属性,并将其值指向于index -->
                <li v-for="(p,index) of persons" :key="index">
                    {
   
   {p.name}}-{
   
   {p.age}}
                    <!-- 增加了input输入框 -->
                    <input type="text">
                </li>
            </ul>
        </div>

上記のレンダリングから、問題が明確にわかりますが、入力ボックスにコンテンツがない場合、追加後に問題は発生しません。しかし、追加する前に対応する入力ボックスに対応するコンテンツを入力すると、追加後に問題があることがわかります。では、なぜそのような問題が発生するのでしょうか? 次の図によるデモンストレーションを見てみましょう。

Indexをキーにすると初期データ以降のデータに応じて仮想DOMが生成され、対応するliタグのキー値はそれぞれ0、1、2となります。データによって初期仮想 DOM が生成された後、新しい実際の DOM が作成され、ページにレンダリングされます。

さらに別のデータを追加すると、新しいデータに基づいて新しい仮想 DOM が生成されます。新しい仮想 DOM は元の仮想 DOM、つまり古い仮想 DOM と比較されます。まず、同じキー値に対応する li を見つけます。仮想 DOM の内容が変更されていない場合は、以前の実際の DOM を直接使用します。仮想 DOM のコンテンツが変更され、新しい実際の DOM が生成され、key="0" のコンテンツが「Zhang San-18」から「Old Liu-30」に変更され、その後、ページ内の以前の実際の DOM が変更されます。置き換えられます。<input type="text"> の比較結果は同じなので、元の内容を保存します。key="1" と key="2" などです。また、key="3" は古い仮想 DOM には見つからないため、新しい実際の DOM が作成されてページにレンダリングされます。

今分かります!

キー値はデータを一意に識別します

key 属性の値をデータの一意の識別子として割り当てると、何が起こるでしょうか? 人物の ID 値を key 属性に割り当てます。具体的なコードは次のとおりです。

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8" />
        <title>key的原理</title>
        <script type="text/javascript" src="../js/vue.js"></script>
    </head>
    <body>
        <!-- 准备好一个容器-->
        <div id="root">
            <h2>人员列表</h2>
            <button @click.once="add">添加一个老刘</button>
            <ul>
                <!-- 绑定了key属性,并将其值指向于p.id -->
                <li v-for="(p,index) of persons" :key="p.id">
                    {
   
   {p.name}}-{
   
   {p.age}}
                    <!-- 增加了input输入框 -->
                    <input type="text">
                </li>
            </ul>
        </div>
​
        <script type="text/javascript">
            new Vue({
                el:'#root',
                data:{
                    persons:[
                        {id:'001',name:'张三',age:18},
                        {id:'002',name:'李四',age:19},
                        {id:'003',name:'王五',age:20}
                    ]
                },
                methods: {
                    add(){
                        const p = {id:'004',name:'老刘',age:40}
                        this.persons.unshift(p)
                    }
                },
            })
        </script>
</html>

 キー属性にバインドされた値がデータ内の一意の識別子であれば、必要な結果が得られることが明確にわかります。対応する概略図は次のとおりです。

各 li タグにバインドされている値は id であるため、新しいメンバーが追加されると、対応する id="004"、対応するキー値は 004 ですが、これは古い仮想 DOM には見つからないため、実際の DOM を使用してページ上にレンダリングされます。他のものについてはあまり説明しませんが、原理は同じです。

要約する

インデックスをキーとして使用する場合は、次の 2 つの問題をダウンロードすることを検討する必要があります。

まず、データを逆順に追加したり、逆順に削除したりして順序を崩すと、不必要な実際の DOM 更新が発生し、インターフェース効果は良いですが、効率が低くなります次に、構造に入力クラスの DOM も含まれている場合、不正な DOM 更新が発生し、インターフェイスで問題が発生します。

では、開発プロセス中にキーをどのように選択すればよいのでしょうか?

まず、ID、携帯電話番号、ID 番号、学生番号、その他の一意の値など、各データの一意の識別子をキーとして使用するのが最善です。逆順追加や逆順削除など、データの順序を崩すような操作がない場合は、リストを表示するために描画するだけなので、インデックスをキーとして使用しても問題ありません。

おすすめ

転載: blog.csdn.net/weixin_51735748/article/details/132155815