フォーム入力バインディング

Vueでは v-model ディレクティブを使うことで、フォーム要素やコンポーネントと「双方向データバインディング」を簡潔に実現できます。ユーザーの入力とVueのデータが常に同期され、フォーム制御が直感的になります。 ここでは、フォーム要素の v-model の利用方法について学習します。 ※コンポーネントの v-model は、コンポーネントの v-modelで学習します。

v-model の基本

v-model ディレクティブは、Vueインスタンスのデータとフォーム要素の値を自動的に同期します。テキスト欄・チェックボックス・ラジオボタン・セレクトボックスはもちろん、コンポーネントにも対応しています。

<!-- template -->
<input v-model="text" type="text" />

<p>
{{ text }}
</p>

この例では、入力欄(input)に文字を入力すると text データが即時に変更され、下の <p> 要素に反映されます。text の値をJavaScriptから変更すると、入力欄(input)の表示も自動的に変わります。

v-model の仕組み

v-model は実際には「バインド」と「イベント監視」を合わせた“糖衣構文”です:

<!-- template -->
<!-- :value がバインド、 @input がイベント監視 -->
<input :value="text" @input="(event) => text = event.target.value" type="text" />

<!-- 上と同じ -->
<input v-model="text" type="text" />

フォームタイプごとにバインドされるプロパティやイベントが異なります:

  • テキスト・テキストエリア:value プロパティと input イベント
  • チェックボックス・ラジオ:checked プロパティと change イベント
  • セレクトボックス:value プロパティと change イベント

例えば、テキストエリア、ラジオボックス、セレクトボックスでは、このように使います:

<script setup lang="ts">
const note = ref('')
const isDone = ref(true)
const showUnDoneOnly = ref(false)
</script>

<template>
  <textarea v-model="note" placeholder="メモを入力" />

  <input v-model="isDone" :value="true" type="radio">完了
  <input v-model="isDone" :value="false" type="radio">未完了

  <select v-model="showUnDoneOnly">
    <option :value="false">
      すべてのタスクを表示
    </option>
    <option :value="true">
      未完了のみ表示
    </option>
  </select>
</template>

それぞれの入力内容が常に v-model の値の変数に格納されます。

💡Tips

  • v-modelとHTMLの value を併用するとvalueは無効になります
  • v-model とイベントハンドラ(例:@change)を併用すると動作に注意が必要
  • データの加工やカスタム検証が必要な場合は、「v-bind」と「v-on」で個別制御が便利

現在の実装の課題

プレイグラウンドで、「未完了のみ表示」チェックボックスを実装しようとしています。

<!-- template -->
<input
  :checked="showUnDoneOnly"
  type="checkbox"
>
未完了のみ表示

この方法では:

  • チェックボックスの「チェックが入っているかどうか(checked)」が、Vueのデータ showUnDoneOnly と連動しない。

チャレンジ

次の手順に沿って、まずは :checked バインディングと @change イベント監視で、値が同期されるよう修正し、 次に v-model で、値が同期されるよう修正しましょう。

1. :checked@change による値の同期

<input>@change イベントを使い、ユーザーがチェックボックスを変更したタイミングで showUnDoneOnly の値を切り替えましょう。これにより、 showUnDoneOnly がユーザー操作に連動して変更されるようになります。

<!-- app.vue: template -->
<input
  :checked="showUnDoneOnly"
  type="checkbox"
  @change="(event) => showUnDoneOnly = event.target.checked"
>
未完了のみ表示

2. v-model による値の同期

次に、 <input>:checkedv-modelに切り替えて、 @change の値変更のコードを削除しましょう。 そうすることで、 v-model だけで、バインドとイベント監視の指定がなくても、値が自動的に同期されるようになります。

もし行き詰まったら、以下のボタンをクリックして解答を見ることができます。

実装後の効果

  • 入力欄やチェックボックスとデータがリアルタイムに連動
  • フォームの状態管理がシンプルかつ直感的に

v-model を使って直感的にフォーム機能を使えるようになりました!

コンポーネント化 パート2
リアクティビティー パート2
リアクティビティー パート1で、データの変更を監視して、変更時に更新を自動的にトリガーする 優れたリアクティビティシステム のrefについて学習しました。 ここでは、computedについて学習しましょう。
ファイル
エディタ
WebContainerを初期化中
ファイルをマウント中
依存関係をインストール中
Nuxtサーバーを起動中
Nuxtが準備完了を待機中
ターミナル