【Vue.jsオフィシャルパートナー】v-forの使い方を分かりやすく解説

v-forはHTMLタグ内で繰り返し構文を行うことができるVue.jsのディレクティブです。
以下のコードのようなscriptタグ内で定義した商品情報のオブジェクトが格納された配列の値をv-forを利用することで、繰り返しのコードの部分を一括で処理することができます。

「Result」のボタンを押すと、プレビュー画面が見られます。

See the Pen
Untitled
by Igami (@IGA_REST)
on CodePen.

v-forはVue.jsのディレクティブの中でも利用するケースが多いディレクティブですので、Vue.jsのオフィシャルパートナーであるSkilledが分かりやすく解説していきます。

v-forとは何か?

Vue.jsでは、HTMLの要素を繰り返し表示するためにv-forディレクティブを使用します。
これは、JavaScriptのforループに似ていますが、Vue.jsの中で特別に設計されています。

初めに記述したコードの中では商品リストの配列をv-forを使用することで、商品情報を繰り返し表示するようにしていました。
具体的には以下のコードの部分です。

<div v-for="product in products"
     :key="product.id"
     class="product-item">
  <div class="product-img-wrap">
    <img class="product-img" :src="product.image" />
    <p class="service-label" v-if="product.isFreeDeliveryFee">送料無料</p>
  </div>
  <p class="product-title">{{ product.name }}</p>
  <p class="product-price">¥{{ product.price }}</p>
</div>

v-for="(変数名) in (配列またはオブジェクト)"

という式でv-forディレクティブは使用することができます。
v-forを定義するとv-for以下の構造の中では指定した変数名で配列内のデータにアクセスすることができます。
今回の課題では、配列に以下のようなオブジェクトが定義されていたので、product.imageproduct.name でオブジェクトの値にアクセスすることができています。

  {
    id: 1,
    name: "SmartPhone V5",
    image: "https://jp.skilled.yashio-corp.com/media/wp-content/uploads/2023/11/アセット-2-100.jpg",
    price: 50000,
    isFreeDeliveryFee: true,
  }

v-forとkey属性

Vue.jsでは、v-forを使用する際に:keyを指定することが推奨されています。:keyは、Vue.jsが各ノードのIDを追跡し、再利用や並べ替えを効率的に行うためのユニークなIDです。

:keyが指定されていない場合、Vue.jsは効率的な更新を行うためにノードの順序を自由に変更することがあります。

例えば、配列内のオブジェクトを削除した時にkey属性を指定していないと意図しない情報が表示されなかったり、別の場所の値が更新されるのなど不具合が発生することがあります。

keyの指定方法は以下の通りでkey属性に指定します。

値は重複しない値を設定する必要があり、今回の例では商品をIDをv-bindを使用して定義しています。

<div v-for="product in products"
     :key="product.id"
     class="product-item">
</div>

v-forとindex

v-forを使用すると、ループの各反復でのインデックスも取得することができます。これは、配列の要素が何番目であるかを知りたい場合や、特定のスタイルを適用したい場合などに便利です。

<template>
  <ul>
    <li v-for="(fruit, index) in fruits" :key="index">
      {{ index }}: {{ fruit }}
    </li>
  </ul>
</template>

<script setup>
import { ref } from 'vue';

const fruits = ref(['Apple', 'Banana', 'Cherry']);
</script>

このコードは、fruits配列の各要素に対して要素を作成します。v-forディレクティブは、配列の各要素に対してループを行い、その要素の値をfruitの変数に、そのインデックス番号をindexの変数に割り当てます。
上記のコードでは、以下のようにインデックスとfruitsの値がリストで表示されています。

v-forでフルーツ表示

v-forのネスト

v-for の中に v-forを入れ子にして連続して、繰り返し処理を行いViewを生成することも可能です。
例えば、以下のようなオブジェクトの配列が定義します。

<script setup>
const products = [
  {
    id: 1,
    name: "SmartPhone V5",
    image: "https://jp.skilled.yashio-corp.com/media/wp-content/uploads/2023/11/アセット-2-100.jpg",
    price: 50000,
    tags: ["iOS", "TV", "Japan"]
  },
  {
    id: 2,
    name: "SmartPhone V4",
    image: "https://jp.skilled.yashio-corp.com/media/wp-content/uploads/2023/11/アセット-1-100.jpg",
    price: 40000,
    tags: ["Android", "US"]
  },
]
</script>

上記の商品のオブジェクトの中にある、tagの配列を表示させるためには以下のようにv-forを定義します。

<template>
  <main>
    <div class="container">
      <h1>商品一覧</h1>
      <div class="product-item-wrap">
        <div v-for="product in products"
             :key="product.id"
             class="product-item">
          <div class="product-img-wrap">
            <img class="product-img" :src="product.image" />
          </div>
          <p class="product-title">{{ product.name }}</p>
          <p class="product-price">¥{{ product.price }}</p>
          <div class="tag-wrap">
            <template v-for="tag in product.tags" :key="tag">
              <label class="tag">{{ tag }}</label>
            </template>
          </div>
        </div>
      </div>
    </div>
  </main>
</template>

... script, styleは省略

v-forを利用すればネストされた複雑なオブジェクトも簡単に表示させることができます。

商品一覧タグ付き

配列の値が更新された時

v-forで指定されている変数がリアクティブな値だった時は値の更新があった時にv-forは自動で検知し、DOMの再生成を行います。
以下のコードは、配列に新しい商品を追加した例です。

<template>
  <main>
    <div class="container">
      <h1>商品一覧</h1>
      <div class="product-item-wrap" v-if="products.length">
        <div v-for="product in products"
             :key="product.id"
             class="product-item">
          <div class="product-img-wrap">
            <img class="product-img" :src="product.image" />
          </div>
          <p class="product-title">{{ product.name }}</p>
          <p class="product-price">¥{{ product.price }}</p>
        </div>
      </div>
      <div v-else>
        <h2 class="empty-title">商品がありません</h2>
      </div>
      <p class="add-btn" @click="addNewItem(products.length)">商品追加</p>
    </div>
  </main>
</template>

<script setup>
  import { reactive } from "vue";

  const products = reactive([]);

  const addNewItem = (length) => {
    const newId = length + 1;
    products.push({
      id: newId,
      name: "SmartPhone V4",
      image: "https://jp.skilled.yashio-corp.com/media/wp-content/uploads/2023/11/アセット-1-100.jpg",
      price: 40000,
      deliveryFee: 50,
    });
  }
</script>

... styleは省略

上記のコードを実行すると以下のように、商品が並んでいくようになっています。

クリックした時の挙動

上記の例ではボタンを押した時に配列に商品が追加される処理を addNewItem関数で定義しています。
また、products変数はref関数で定義されており、リアクティブな値になっているので、v-forでは値が更新された時にDOMを再生成しています。
このようにv-forを利用することで、値の更新にも柔軟に対応させることが可能です。

Vue.jsを学習するならSkilled(スキルド)

スキルドではフロントエンド専門の実践特化型のプログラミング学習サービスです。

コーディングからフロントエンジニアまでの学習をカバーしており、コーディングしながら実践的に学習することで知識ではなく『スキル』が身につけられるサービスとなっております。

現在無料体験キャンペーンを行っていますので、気になる方はぜひ無料体験を利用してみてください。