

<http://gihyo.jp/dev/serial/01/vuejs/0002> を参考にしてVue.jsを勉強しています。  
その中で、

[code]

    <div id="example">
      <li v-for="item in items" v-bind:key="item.name">
        <p>{{ item.name }} は {{ item.price }}円</p>
      </li>
    </div>
    
[/code]

とhtmlを書いてある時と、

[code]

    <div id="example">
      <li v-for="item in items">
        <p>{{ item.name }} は {{ item.price }}円</p>
      </li>
    </div>
    
[/code]

とhtmlを書いてある時の２種類があって、どちらもjsは同じコードでv-bind:key
を使う時と使わない時の違いがわかりません。v-bind:keyがある時とない時ではどう違うのでしょうか？


CC BY-SA 3.0
2018-03-09T03:21:43.873
42250
2018-08-15T12:00:44.200
27670
question
html vue.js
v-bind:key を使う時と使わない時の違い


まず、`key`を指定しないと警告が出ますし、なるべく指定することが推奨されています。

公式ガイド  
[List Rendering - key (英語)](https://v2.vuejs.org/v2/guide/list.html#key),
[(日本語)](https://jp.vuejs.org/v2/guide/list.html#key)

> Vue が各ノードの識別情報を追跡できるヒントを与えるために、また、先ほど説明したような既存の要素の再利用と並び替えができるように、一意な key
> 属性を全てのアイテムに与える必要があります。

要はキーを指定すれば、リストの要素の順番が入れ替わったりしたときに、変更前と変更後でキーが同じ要素は同じものだとみなされて、適宜DOM要素の移動が起こります。

逆に指定しなければ、DOM要素の移動は起こらず、その場で各要素を変更します。しかしこれは、List
Renderingされる要素がフォーム要素などの「状態」を持つ(statefulな)要素である場合、意図しない動作になるのでやってはいけません。公式ガイドにもそうかいてあります。

> この標準のモードは効率がいいです。しかしこれは、描画されたリストが子コンポーネントの状態や、一時的な DOM
> の状態に依存していないときにだけ適しています (例: フォームのインプットの値)。

  * キーを指定しない場合  
[DEMO1(JSFiddle)](https://jsfiddle.net/a7kgm989/7/)  
上で述べたやってはいけない例です。「シフト」ボタンを押すとリストが左にローテート(シフト)します。  
適当にテキストボックスに入力してからボタンを押すと、テキストボックスが移動していないことが分かります。

  * キーを指定した場合  
[DEMO2(JSFiddle)](https://jsfiddle.net/b20919t1/1/)  
今度はシフトするとテキストボックスも移動します。シフトの際、Vueはキーを元にしてシフト後の各要素がシフト前のどの要素と対応しているのかが分かるため、それに応じてDOM要素を移動します。

* * *

# 補足

質問文の例では、`v-for`で表示されるDOM要素は状態を持たない要素なので、キーを指定してもしなくても外から見た動作に違いはありません(ただし、どのように変更が反映されるかという内部的な動作は変わります)。


CC BY-SA 3.0
2018-03-09T08:20:23.127
42266
2018-03-09T08:26:42.547
2022-09-27T22:35:34.400
-1
20206
42250
answer