採点されません。匿名です。 間違えることは学習の一部です。読むだけでもかまいません。

L08 ch03 — v-for で リスト描画

テクノロジ系 / L08 vue-basic — Vue 3 入門

L08 ch03 — v-for で リスト描画

配列を反復して DOM 要素を量産

ゴール

  • v-for="item in items" 構文
  • :key の重要性
  • 配列メソッド (push) で動的更新

基本

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

const fruits = ref(['りんご', 'みかん', 'ぶどう'])
</script>

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

オブジェクトのリスト

<script setup>
const tasks = ref([
  { id: 1, title: '買い物' },
  { id: 2, title: '掃除' },
])
</script>

<template>
  <ul>
    <li v-for="task in tasks" :key="task.id">
      {{ task.title }}
    </li>
  </ul>
</template>

key 属性の重要性

<!-- ❌ index を key にすると並び替えで DOM 混乱 -->
<li v-for="(item, i) in items" :key="i">

<!-- ✅ ユニーク ID を key に -->
<li v-for="item in items" :key="item.id">

→ Vue は key で要素を識別、再利用する

動的追加

<script setup>
const tasks = ref([])
const newTitle = ref('')

function addTask() {
  if (!newTitle.value.trim()) return
  tasks.value.push({
    id: Date.now(),
    title: newTitle.value,
  })
  newTitle.value = ''
}
</script>

<template>
  <input v-model="newTitle" />
  <button @click="addTask">追加</button>
  <ul>
    <li v-for="t in tasks" :key="t.id">{{ t.title }}</li>
  </ul>
</template>

index 付き

<li v-for="(item, index) in items" :key="item.id">
  {{ index + 1 }}: {{ item.title }}
</li>

罠: v-for と v-if 同一要素

<!-- ❌ Vue 3 では if が外側評価 → 意図と違う動作 -->
<li v-for="t in tasks" v-if="t.done">...

<!-- ✅ template で分離 -->
<template v-for="t in tasks" :key="t.id">
  <li v-if="t.done">{{ t.title }}</li>
</template>

drill

drill/ — fill-vfor

ハンズオン

ch03-v-for 演習ガイド

受講生向け演習問題集

採点の仕組み (読んでから始めてください)

採点テストは 「お題の通りに動くか」 を機械的にチェックします。

ドリルごとに 3つのタイプ があるので、各ドリル冒頭の 【タイプ】 を確認してください。

タイプ fill (穴埋め問題) — 文法・APIを知っているか

  • ___ (3個並んだアンダースコア) の空欄を埋める
  • 既存の <template> のテキストやボタン順は そのまま
  • ロジック自由度: 低 (お題どおりに直す)

タイプ add (機能追加問題) — 既存コードに機能を足せるか

  • 既存コードを残したまま、新しい機能を 追加 する
  • 実装方法は自由 (関数名・変数名・内部ロジックは好きに)
  • ただしテストが要求する見た目 (表示テキスト・ボタンの並び順) は守る
  • 既存テストを壊さないこと

タイプ build (ゼロベース実装問題) — 仕様から実装を組み立てられるか

  • ほぼ空の App.vue から 自力で全部書く
  • <template> 構造・id/class・内部ロジック: 完全に自由
  • 守るのは画面の機能仕様だけ: 表示するテキスト・ボタンの操作で何が起きるか
  • 一番ハードだが、実装力が一番つくタイプ

3タイプ共通で守ること

  • ファイル名 (App.vue) は変えない
  • tests/ フォルダは触らない (採点ロジック)
  • テンプレートの 表示テキスト (「カウント:」等) はテストが見ているので残す

このガイドのドリル一覧

#ドリル名タイトルタイプ難易度
101-fill-vforv-for + :key - 配列のループレンダリング🔧 穴埋め

> 詰まったら ヒント ページを開く。それでも分からなければ講師に質問。

ドリル 1: v-for + :key - 配列のループレンダリング

ドリル名: 01-fill-vfor

> 🔧 【タイプ: 穴埋め問題】 ___ の部分を埋めて完成させてください。既存のコード構造は変えないこと。

問題

___ を埋めて、入力したタスクをリストに追加するアプリを完成させよ。___ は全部で4箇所ある。

<script setup>
import { ref } from 'vue'
const newTitle = ref('')
const tasks = ref([])

function addTask() {
  if (!newTitle.value.trim()) return
  tasks.value.push({ title: newTitle.value })
  newTitle.value = ''
}
</script>

<template>
  <input ___="newTitle" placeholder="タスク名を入力" />  <!-- ___1: 入力値とデータを双方向に繋ぐディレクティブ -->
  <button @click="addTask">追加</button>
  <ul>
    <li ___ ="task in tasks" :key="task.title">          <!-- ___2: 配列を繰り返すディレクティブ -->
      {{ ___ }}                                          <!-- ___3: タスクのタイトルを表示 -->
    </li>
  </ul>
  <p>{{ tasks.___ }} 件</p>                              <!-- ___4: 配列の要素数を返すプロパティ -->
</template>

確認方法

  1. タスク名を入力して「追加」をクリックするとリストに追加される
  2. 件数が増える
  3. 空文字では追加されない

ドリル 1: ヒント

ドリル名: 01-fill-vfor

> ⚠️ 自力で考えてから読んでください

  • ___1: 入力欄とデータを「双方向」に繋ぐ Vue ディレクティブ。v-???
  • ___2: 配列をループして各要素を li として表示するディレクティブ。v-???
  • ___3: task オブジェクトの title プロパティ
  • ___4: JavaScript 配列の要素数を返す標準プロパティ

考えてみよう

既定では正解・不正解の判定はしません。自分のペースで「答えを見る」を。採点してほしい場合だけ「採点してほしい」を押してください。

ch03-v-for 演習ガイド

受講生向け演習問題集

採点の仕組み (読んでから始めてください)

採点テストは 「お題の通りに動くか」 を機械的にチェックします。

ドリルごとに 3つのタイプ があるので、各ドリル冒頭の 【タイプ】 を確認してください。

タイプ fill (穴埋め問題) — 文法・APIを知っているか

  • ___ (3個並んだアンダースコア) の空欄を埋める
  • 既存の <template> のテキストやボタン順は そのまま
  • ロジック自由度: 低 (お題どおりに直す)

タイプ add (機能追加問題) — 既存コードに機能を足せるか

  • 既存コードを残したまま、新しい機能を 追加 する
  • 実装方法は自由 (関数名・変数名・内部ロジックは好きに)
  • ただしテストが要求する見た目 (表示テキスト・ボタンの並び順) は守る
  • 既存テストを壊さないこと

タイプ build (ゼロベース実装問題) — 仕様から実装を組み立てられるか

  • ほぼ空の App.vue から 自力で全部書く
  • <template> 構造・id/class・内部ロジック: 完全に自由
  • 守るのは画面の機能仕様だけ: 表示するテキスト・ボタンの操作で何が起きるか
  • 一番ハードだが、実装力が一番つくタイプ

3タイプ共通で守ること

  • ファイル名 (App.vue) は変えない
  • tests/ フォルダは触らない (採点ロジック)
  • テンプレートの 表示テキスト (「カウント:」等) はテストが見ているので残す

このガイドのドリル一覧

#ドリル名タイトルタイプ難易度
101-fill-vforv-for + :key - 配列のループレンダリング🔧 穴埋め

> 詰まったら ヒント ページを開く。それでも分からなければ講師に質問。

ドリル 1: v-for + :key - 配列のループレンダリング

ドリル名: 01-fill-vfor

> 🔧 【タイプ: 穴埋め問題】 ___ の部分を埋めて完成させてください。既存のコード構造は変えないこと。

問題

___ を埋めて、入力したタスクをリストに追加するアプリを完成させよ。___ は全部で4箇所ある。

<script setup>
import { ref } from 'vue'
const newTitle = ref('')
const tasks = ref([])

function addTask() {
  if (!newTitle.value.trim()) return
  tasks.value.push({ title: newTitle.value })
  newTitle.value = ''
}
</script>

<template>
  <input ___="newTitle" placeholder="タスク名を入力" />  <!-- ___1: 入力値とデータを双方向に繋ぐディレクティブ -->
  <button @click="addTask">追加</button>
  <ul>
    <li ___ ="task in tasks" :key="task.title">          <!-- ___2: 配列を繰り返すディレクティブ -->
      {{ ___ }}                                          <!-- ___3: タスクのタイトルを表示 -->
    </li>
  </ul>
  <p>{{ tasks.___ }} 件</p>                              <!-- ___4: 配列の要素数を返すプロパティ -->
</template>

確認方法

  1. タスク名を入力して「追加」をクリックするとリストに追加される
  2. 件数が増える
  3. 空文字では追加されない

ドリル 1: ヒント

ドリル名: 01-fill-vfor

> ⚠️ 自力で考えてから読んでください

  • ___1: 入力欄とデータを「双方向」に繋ぐ Vue ディレクティブ。v-???
  • ___2: 配列をループして各要素を li として表示するディレクティブ。v-???
  • ___3: task オブジェクトの title プロパティ
  • ___4: JavaScript 配列の要素数を返す標準プロパティ

ch03-v-for 演習解説

⚠️ 自力でドリルを解いてから読んでください

ドリル 1: v-for + :key - 配列のループレンダリング — 模範解答

ドリル名: 01-fill-vfor

<script setup>
import { ref } from 'vue'
const newTitle = ref('')
const tasks = ref([])

function addTask() {
  if (!newTitle.value.trim()) return
  tasks.value.push({ title: newTitle.value })
  newTitle.value = ''
}
</script>

<template>
  <input v-model="newTitle" placeholder="タスク名を入力" />
  <button @click="addTask">追加</button>
  <ul>
    <li v-for="task in tasks" :key="task.title">
      {{ task.title }}
    </li>
  </ul>
  <p>{{ tasks.length }} 件</p>
</template>

ドリル 1: v-for + :key - 配列のループレンダリング — 解説

ドリル名: 01-fill-vfor

<script setup>
import { ref } from 'vue'
const newTitle = ref('')
const tasks = ref([])

function addTask() {
  if (!newTitle.value.trim()) return
  tasks.value.push({ title: newTitle.value })
  newTitle.value = ''
}
</script>

<template>
  <input v-model="newTitle" placeholder="タスク名を入力" />
  <button @click="addTask">追加</button>
  <ul>
    <li v-for="task in tasks" :key="task.title">
      {{ task.title }}
    </li>
  </ul>
  <p>{{ tasks.length }} 件</p>
</template>
  • ___1v-model
  • ___2v-for
  • ___3task.title
  • ___4length

Q: v-for と v-model の空欄を埋める

問題

___ を埋めて、入力したタスクをリストに追加するアプリを完成させよ。___ は全部で4箇所ある。

<script setup>
import { ref } from 'vue'
const newTitle = ref('')
const tasks = ref([])

function addTask() {
  if (!newTitle.value.trim()) return
  tasks.value.push({ title: newTitle.value })
  newTitle.value = ''
}
</script>

<template>
  <input ___="newTitle" placeholder="タスク名を入力" />  <!-- ___1: 入力値とデータを双方向に繋ぐディレクティブ -->
  <button @click="addTask">追加</button>
  <ul>
    <li ___ ="task in tasks" :key="task.title">          <!-- ___2: 配列を繰り返すディレクティブ -->
      {{ ___ }}                                          <!-- ___3: タスクのタイトルを表示 -->
    </li>
  </ul>
  <p>{{ tasks.___ }} 件</p>                              <!-- ___4: 配列の要素数を返すプロパティ -->
</template>

確認方法

  1. タスク名を入力して「追加」をクリックするとリストに追加される
  2. 件数が増える
  3. 空文字では追加されない

ヒント: v-for と v-model の空欄

  • ___1: 入力欄とデータを「双方向」に繋ぐ Vue ディレクティブ。v-???
  • ___2: 配列をループして各要素を li として表示するディレクティブ。v-???
  • ___3: task オブジェクトの title プロパティ
  • ___4: JavaScript 配列の要素数を返す標準プロパティ

解答: v-for と v-model の空欄

<script setup>
import { ref } from 'vue'
const newTitle = ref('')
const tasks = ref([])

function addTask() {
  if (!newTitle.value.trim()) return
  tasks.value.push({ title: newTitle.value })
  newTitle.value = ''
}
</script>

<template>
  <input v-model="newTitle" placeholder="タスク名を入力" />
  <button @click="addTask">追加</button>
  <ul>
    <li v-for="task in tasks" :key="task.title">
      {{ task.title }}
    </li>
  </ul>
  <p>{{ tasks.length }} 件</p>
</template>
  • ___1v-model
  • ___2v-for
  • ___3task.title
  • ___4length