6.

Vue.js v-model 完全ガイド(双方向データバインディングと修飾子)

編集
この記事の要点
  • v-modelvalue 属性と input イベントを束ねた 双方向データバインディングのシンタックスシュガー
  • 基本: + data() { return { message: "" } }
  • 修飾子: .lazy(change イベント)/ .trim(前後空白除去)/ .number(数値変換)
  • checkbox / radio / select でも使えるが、初期値や bind 値の型に注意
  • カスタムコンポーネントでは Vue 3 は modelValue + update:modelValue、Vue 2 は value + input

v-model とは

Vue.js の v-model は、フォーム入力要素と Vue インスタンスのデータプロパティを双方向にバインドするディレクティブです。ユーザーが入力を変えれば data が、data を更新すれば入力欄が、それぞれ自動更新されます。

これは内部的には 「value 属性のバインド」+「input イベントのリスナー」のシンタックスシュガーです:





基本の使い方

入力中: {{ message }}

入力するたびに {{ message }} が即座に反映されます。

修飾子 (Modifiers)

修飾子動作用途
.lazyinput ではなく change イベントで同期確定時のみ更新したい(IME 対応)
.number入力値を Number にキャスト数値入力欄
.trim前後の空白を除去ユーザー名・メール等










checkbox / radio / select との連携




















computed と組み合わせる

v-model だけで完結しない加工処理は computedwatch と組み合わせます:

createApp({
  data() {
    return { firstName: '', lastName: '' }
  },
  computed: {
    fullName() {
      return `${this.firstName} ${this.lastName}`.trim();
    }
  },
  watch: {
    fullName(newVal) {
      console.log('変更:', newVal);
    }
  }
}).mount('#app');

computed プロパティに v-model する(setter)

computed は通常読み取り専用ですが、getter/setter を定義すれば v-model にも使えます:

computed: {
  fullName: {
    get() {
      return `${this.firstName} ${this.lastName}`;
    },
    set(value) {
      const parts = value.split(' ');
      this.firstName = parts[0];
      this.lastName  = parts[1] ?? '';
    }
  }
}

カスタムコンポーネントでの v-model

Vue 3 (modelValue / update:modelValue)

// MyInput.vue




// 親側

Vue 3: 複数の v-model



Vue 2 (value / input)

// MyInput.vue (Vue 2)


IME (日本語入力) で困る話

デフォルトの v-modelinput イベントで同期するため、IME 変換中の未確定文字も data に反映されてしまいます。検索ボックスなどで「タイピング中に都度 API を叩いて重い」問題の原因です:







よくあるトラブル

症状原因対処
入力が反映されないdata() に message を定義していない必ず data に初期値を宣言
v-model.number で空入力時 NaN空文字を Number キャストv-model だけにして手動 parseInt
v-model.lazy で送信ボタンを押しても古い値change が発火していない送信前に明示的に blur
カスタムコンポで v-model 効かないprops/emit 名が違うVue 3 は modelValue / update:modelValue

FAQ

Q: v-bind と v-model の違い
A: v-bind は片方向(data → DOM のみ)、v-model は双方向

Q: v-model のままで textarea や contenteditable に使える?
A: textarea は v-model 可。contenteditable は標準サポートなしで、自前で input イベントを拾う必要があります。

Q: ref とどっちを使うべき?
A: Composition API の ref/reactive + v-model はそのまま動きます。Options API の data() と同じ感覚で使えます。

編集
Post Share
子ページ

子ページはありません

同階層のページ
  1. インストール(ファイルのダウンロード)
  2. npmを使用したプロジェクトの作成(mac)
  3. for 繰り返し処理
  4. ifの条件分岐とtemplateを用いたグループ化
  5. on:click クリック時のイベント処理
  6. modelとdata フォーム入力値とDOMへの即時反映
  7. computed(算出プロパティ)と使い方とdataとの違い
  8. ライフサイクルフック(created / mounted / updated / destroyedの使い方)
  9. $nextTickの使い方(ライフサイクルフック)
  10. メソッドの定義方法
  11. エラー一覧
  12. ルーティング設定
  13. aリンクの貼り方と動的URLの作成
  14. Mixinを利用した共通処理の記述方法
  15. v-bindによるデータ連携
  16. ヘッダー/フッターの共通コンポーネント
  17. ナビゲーションの現在ページをハイライトする方法
  18. 画面サイズの取得方法