Vue.js: テンプレート構文

最終更新:2026-10-20

Vueのテンプレート構文は、HTMLの宣言型拡張です。標準のHTMLに「ディレクティブ」と「補間」を追加することで、データをDOMにレンダリングできるようになります。テンプレート構文の90%はHTMLと類似しているため、HTMLに慣れている人なら誰でも30分で使い始めることができます。

Vueのテンプレートの核心となるのは、補間(データの表示)+ディレクティブ(プロパティやイベントのバインディング)+式(JavaScriptの実行)という3つの重要な要素です。このレッスンでは、これら3つの要素を標準的な方法で使用する方法について解説します。

関連ディレクティブ:v-text v-html v-once

1. 学習内容


2. Eコマースの商品カードの表示要件

(1) 課題:30種類の商品――30回もコピー&ペーストしなければならないのか?

アリスは、ECサイトの管理ダッシュボードを構築しています。彼女は30枚の商品カードを表示する必要があります。彼女の当初のアプローチは次のとおりです:

HTML
<!-- Copy and paste 30 times, nightmare... -->
<div class="product-card">
  <h3>iPhone 15 Pro</h3>
  <p>Price: $999</p>
  <button>Edit</button>
</div>
<div class="product-card">
  <h3>MacBook Pro</h3>
  <p>Price: $2499</p>
  <button>Edit</button>
</div>
<!-- ... And also 28 more ... -->

プロダクトマネージャーのチャーリーが「通貨記号が表示されるように価格の表示形式を変更してください」と言ったとき:

「アリス、30個のファイルを手作業で編集するのは無理だよ。それに、来月商品数が5,000個になったらどうするの? 動的なテンプレートが必要だ。」

(2) Vueテンプレートの解決策:コンポーネント1つ、データポイント30個

テンプレートコード5行 × 30商品 = コピー&ペーストは一切不要。商品名や価格が変更されると、Vueが自動的にDOMを更新します。

(3) 収益

Vueテンプレートを採用した後:


3. 補間:Mustache {{ }}

(1) 補間を実装する4つの方法

構文 結果 例
{{ var }} 変数の値を表示 <p>{{ username }}</p> → アリス
{{ expr }} JS式の結果を表示 <p>{{ count + 1 }}</p> → 6
{{ fn() }} 関数呼び出しの戻り値 <p>{{ formatDate(date) }}</p> → 2026年7月2日
{{ obj.prop }} オブジェクトのプロパティへのアクセス <p>{{ user.name }}</p> → アリス

(2) 補間の5つの主な特徴

(3) 補間とv-textの違い

▶ サンプル:補間の記述方法のバリエーション

▶ 試してみよう

出力:

TEXT
Alice / 7(count = 3 のとき)
Passed(score が 60 以上。60 未満なら Failed に切り替わる)
2026/7/2、Bob

4. テキストディレクティブ:v-text / v-html / v-once

(1) 3つのコマンドの比較

コマンド 機能 用途 セキュリティ
{{ }} 補間 テキスト補間 デフォルト設定 ✅ セキュリティ
v-text 要素の textContent を設定する 補間の代替構文 ✅ 安全
v-html 要素の innerHTML を設定する リッチテキストをレンダリングする(使用には注意が必要です) ⚠️ XSS のリスク
v-once 一度レンダリングすれば、その後は更新されない 静的最適化 ✅ セキュリティ

(2) v-html に関する警告

(3) v-once のパフォーマンス最適化


5. プロパティのバインディング:v-bind と : 短縮表記

(1) v-bind の基礎

(2) クラスとスタイルのバインディング(要点)

(3) スタイルのバインディング

▶ サンプル:v-bind の 5 つの活用法

▶ 試してみよう

出力:

TEXT
img の src に imageUrl、alt に imageAlt が入る
A は class="active"、B は class="active text-danger"
Profile のリンクは href="/users/42" になる

6. イベントバインディング:v-on と @ の省略形

(1) v-on の基本

(2) 一般的なイベント修飾子 (9)

(3) 修飾子の連鎖

▶ サンプル:v-on の記述方法 5 通り

▶ 試してみよう

出力:

TEXT
Click → handleClick() が実行される
「+」→ count が 1 増えて表示が更新される
Delete → handleDelete(item.id, event) が呼ばれる
Save → stop してから prevent して handle()、Ctrl+Enter で submit()

(1) 📊 . テンプレートとHTMLのクイックリファレンス

要素 HTML構文 Vue構文 説明
静的テキスト <p>Hello</p> <p>{{ msg }}</p> 動的にする
静的プロパティ <img src="x.jpg"> <img :src="url"> 動的プロパティに変更
静的クラス <div class="box"> <div :class="cls"> 動的に変更
静的スタイル <div style="color: red"> <div :style="sty"> 動的スタイルに変更
クリックイベント <button onclick="fn()"> <button @click="fn"> Vueを編集
条件付きレンダリング なし <div v-if="ok"> Vue固有
リストのレンダリング なし <div v-for="i in list"> Vue固有

(2) 📊 . よくある5つの間違い

エラー 症状 解決策
.value を削除 テンプレートには {{ count }} を、JS には count.value を記述 テンプレートでは自動的に展開されるが、JS では .value が必要
{{ }} での if/for の記述 コンパイルエラー v-if / v-for ディレクティブの使用
v-html XSS ユーザー入力 <script> 実行 DOMPurify による対策
インライン関数が $event を受け取らなかった イベントオブジェクトにアクセスできない @click="fn($event)" 明示的に渡す
修飾子の順序が間違っている バブリングの防止に失敗した .stop が .prevent の前にある(必要に応じて)


7. 式の制限(特定の文は使用不可)

(1) テンプレート式とJavaScript文

(2) 式と計算プロパティ

シナリオ 式の使用 計算プロパティの使用
簡単な計算(演算子1~2個) ✅ ❌
複雑なロジック(多段階、ループ) ❌ ✅
キャッシュが必要 ❌ ✅
必須パラメータ ✅ ❌ (代わりにメソッドを使用してください)

8. Edgeディレクティブ:v-pre / v-cloak

(1) v-pre: コンパイルをスキップ

シナリオ:Vueのテンプレート構文そのものを示す場合(例:チュートリアル、ドキュメントサイトなど)。

(2) v-cloak:コンパイル前に非表示にする

シナリオ:コンパイル前にユーザーが {{ message }} が点滅しているのを目にするのを防ぐ。


9. 総合演習:動的な商品カード

▶ サンプル:基本商品カード

▶ 試してみよう

出力:

TEXT
iPhone 15 Pro / $999 / In Stock(stock 50)
Add to Cart を押すとコンソールに Added iPhone 15 Pro
stock 0 の商品は Out of Stock 表示になりボタンが無効化される


関連ディレクティブ:v-text v-html v-once

❓ よくある質問

Q {{ }} と v-text の違いは何ですか?
A 両者は同じ効果を持ち、どちらも要素の textContent を設定します。違いは、{{ }} は静的テキスト (<p>Hi, {{ name }}</p>) と併用できるのに対し、v-text は要素全体を占めなければならない (<p v-text="msg"></p>) という点です。柔軟性を高めるため、{{ }}の使用をお勧めします。
Q v-html は安全ですか?
A いいえ、安全ではありません。v-html は文字列を HTML として解析するため、悪意のあるユーザーが <script> を注入してサイトを攻撃する可能性があります。データソース(自分で作成したMarkdownレンダラーなど)を100%信頼できる場合を除き、補間には{{ }}を使用するか、事前にDOMPurify.sanitize()でデータをサニタイズしてください。
Q v-on修飾子チェーンの実行順序はどのようになりますか?
A 左から右へです。例えば、@click.stop.preventはまずstopPropagation()を呼び出し、次にpreventDefault()を呼び出します。
Q v-bind は略せますか?v-on も略せますか?
A v-bind の略記は :(v-bind は含まない)であり、v-on の略記は @(推奨)です。どちらの略記も Vue 2 以降でサポートされている公式の表記であり、IDE のシンタックスハイライトや自動補完機能でもサポートされています。
Q テンプレート内で if/else 文を使用できますか?
A いいえ。テンプレート式は値を返さなければなりませんが、if や for は式ではなく文です。条件付きレンダリングを実装するには、v-if、v-else-if、v-else ディレクティブを使用してください。
Q v-bind を使って複数のクラスを動的に切り替えるにはどうすればよいですか?
A オブジェクト構文 :class="{ active: isActive, 'text-danger': hasError }" を使用します。あるいは、配列構文 :class="[activeClass, errorClass]" を使用します。この 2 つを組み合わせて使用することも可能です::class="[isActive && 'active', { 'error': hasError }]"。
Q Ctrl+S のキーボードショートカットをどのように検知すればよいですか?
A システム修飾子 @keyup.ctrl.s="save" または @keydown.ctrl.s.prevent="save" を使用してください(ブラウザのデフォルトの保存ダイアログが表示されないようにするには、.prevent を追加してください)。Vue 3 では、正確な修飾子 .exact もサポートされています。たとえば、@click.ctrl.exact では Ctrl キーのみが押される必要があり、他のキーは許可されません。

📖 まとめ


📝 練習問題

  1. 基礎問題(難易度:⭐)

    以下の内容を含むユーザーカードを表示する Vue 3 コンポーネントを作成してください:

    • ユーザー名(補間)
    • プロフィール画像(v-bind)
    • 「フォロー」ボタン(v-on)
    • オンライン/オフラインの状態(動的切り替え)

    使用データ:ユーザーオブジェクト { name: 'Alice', avatar: 'alice.jpg', online: true }

  2. 上級問題(難易度:⭐⭐)

    簡単なToDoリストを実装する:

    • 入力フィールド(v-model は現時点では使用されていません。v-bind:value + @input を使用してシミュレートしています)
    • 「追加」ボタン (@click + 式)
    • リストのレンダリング(v-for;これについては次のレッスンで解説します)
    • 各項目には削除ボタンがあります(@click + パラメータの受け渡し)

    データ:const todos = ref(['Learn Vue', 'Build app', 'Deploy'])

  3. チャレンジ問題(難易度:⭐⭐⭐)

    以下の機能をサポートする、完全な商品詳細カードコンポーネントを作成してください:

    1. 5種類の商品ステータスバッジ(在庫あり/在庫切れ/予約受付中/セール中/販売終了)
    2. 5つの状態はそれぞれ異なるクラスの色に対応しています(オブジェクト構文を使用して一括でバインドされます)。
    3. 数量の増減ボタン(クリックで増減)
    4. 数量が在庫数以上の場合、「カートに追加」ボタンを無効にする(動的に無効化)
    5. 少なくとも3つのイベント修飾子(@click.stop、@submit.preventなど)
Web-Tutorial.com

Web-Tutorial 技術チーム

複数の開発者によって共同維持されているプログラミングチュートリアルプラットフォーム。各チュートリアルは専門分野の開発者が執筆・レビューしています。正確で信頼性の高いコンテンツを目指しています — 問題を見つけた場合はお知らせください。

100%