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

# 基本的な使い方

form の input 要素や textarea 要素、 select 要素に双方向データバインディングを付与するためには、v-modelを使用することができます。v-modelは、要素を更新する適切な方法を入力の種類に基づき自動的に選択します。少し魔法のようですが、本来v-modelは糖衣構文(syntax sugar)であり、ユーザの入力イベントに応じてデータを更新し、さらにエッジケースに対する特別な配慮をしてくれます。

TIP

v-model はフォーム要素のvalue属性やchecked属性、selected属性の初期値を無視します。v-modelは常に、現在アクティブなインスタンスのdataを信頼できる情報源として扱います。初期値の宣言は JavaScript 側、コンポーネントのdataオプション内で行ってください。

内部的には、v-modelは異なる input 要素に対し異なるプロパティを使用し、異なるイベントを送出します。

  • text および textarea 要素には、valueプロパティとinputイベントを用います
  • チェックボックスおよびラジオボタンには、checkedプロパティとchangeイベントを用います
  • select フィールドには、valueプロパティとchangeイベントを用います

Note

IME (opens new window) を必要とする言語 (中国語、日本語、韓国語など) においては、IME による入力中にv-modelが更新を行わないことに気づくでしょう。このような入力に対しても同様に扱いたい場合は、代わりにinput イベントを使用してください。

# テキスト

<input v-model="message" placeholder="edit me" />
<p>Message is: {{ message }}</p>
1
2

See the Pen Handling forms: basic v-model by Vue (@Vue) on CodePen.

# 複数行テキスト

<span>Multiline message is:</span>
<p style="white-space: pre-line;">{{ message }}</p>
<br />
<textarea v-model="message" placeholder="add multiple lines"></textarea>
1
2
3
4

See the Pen Handling forms: textarea by Vue (@Vue) on CodePen.

textarea への挿入は機能しません。代わりにv-modelを用いてください。

<!-- bad -->
<textarea>{{ text }}</textarea>

<!-- good -->
<textarea v-model="text"></textarea>
1
2
3
4
5

# チェックボックス

単一のチェックボックスと boolean 値:

<input type="checkbox" id="checkbox" v-model="checked" />
<label for="checkbox">{{ checked }}</label>
1
2

See the Pen Handling forms: checkbox by Vue (@Vue) on CodePen.

同じ配列にバインドされた複数のチェックボックス:

<div id="v-model-multiple-checkboxes">
  <input type="checkbox" id="jack" value="Jack" v-model="checkedNames" />
  <label for="jack">Jack</label>
  <input type="checkbox" id="john" value="John" v-model="checkedNames" />
  <label for="john">John</label>
  <input type="checkbox" id="mike" value="Mike" v-model="checkedNames" />
  <label for="mike">Mike</label>
  <br />
  <span>Checked names: {{ checkedNames }}</span>
</div>
1
2
3
4
5
6
7
8
9
10
Vue.createApp({
  data() {
    return {
      checkedNames: []
    }
  }
}).mount('#v-model-multiple-checkboxes')
1
2
3
4
5
6
7

See the Pen Handling forms: multiple checkboxes by Vue (@Vue) on CodePen.

# ラジオ

<div id="v-model-radiobutton">
  <input type="radio" id="one" value="One" v-model="picked" />
  <label for="one">One</label>
  <br />
  <input type="radio" id="two" value="Two" v-model="picked" />
  <label for="two">Two</label>
  <br />
  <span>Picked: {{ picked }}</span>
</div>
1
2
3
4
5
6
7
8
9
Vue.createApp({
  data() {
    return {
      picked: ''
    }
  }
}).mount('#v-model-radiobutton')
1
2
3
4
5
6
7

See the Pen Handling forms: radiobutton by Vue (@Vue) on CodePen.

# セレクト

単一のセレクト:

<div id="v-model-select" class="demo">
  <select v-model="selected">
    <option disabled value="">Please select one</option>
    <option>A</option>
    <option>B</option>
    <option>C</option>
  </select>
  <span>Selected: {{ selected }}</span>
</div>
1
2
3
4
5
6
7
8
9
Vue.createApp({
  data() {
    return {
      selected: ''
    }
  }
}).mount('#v-model-select')
1
2
3
4
5
6
7

See the Pen Handling forms: select by Vue (@Vue) on CodePen.

Note

v-modelの式の初期値がいずれのオプションとも一致しない場合、<select>要素は 未選択 の状態で描画されます。これにより iOS では最初のアイテムが選択できなくなります。なぜなら iOS はこのような場合に change イベントを発火させないためです。したがって、上記の例で示したように、valueを持たないdisabled なオプションを追加しておくことをおすすめします。

複数個のセレクト(配列にバインド):

<select v-model="selected" multiple>
  <option>A</option>
  <option>B</option>
  <option>C</option>
</select>
<br />
<span>Selected: {{ selected }}</span>
1
2
3
4
5
6
7

See the Pen Handling forms: select bound to array by Vue (@Vue) on CodePen.

動的なオプションをv-forにより描画:

<div id="v-model-select-dynamic" class="demo">
  <select v-model="selected">
    <option v-for="option in options" :value="option.value">
      {{ option.text }}
    </option>
  </select>
  <span>Selected: {{ selected }}</span>
</div>
1
2
3
4
5
6
7
8
Vue.createApp({
  data() {
    return {
      selected: 'A',
      options: [
        { text: 'One', value: 'A' },
        { text: 'Two', value: 'B' },
        { text: 'Three', value: 'C' }
      ]
    }
  }
}).mount('#v-model-select-dynamic')
1
2
3
4
5
6
7
8
9
10
11
12

See the Pen Handling forms: select with dynamic options by Vue (@Vue) on CodePen.

# 値のバインディング

ラジオやチェックボックス、セレクトの option において、v-modelでバインディングされる値は通常は静的な文字列(チェックボックスの場合は boolean も)です:

<!-- チェックされているとき`picked` は文字列"a"になります -->
<input type="radio" v-model="picked" value="a" />

<!-- toggle` は true または false のどちらかです -->
<input type="checkbox" v-model="toggle" />

<!-- 最初のオプションが選択されているとき`selected` は文字列"abc"です -->
<select v-model="selected">
  <option value="abc">ABC</option>
</select>
1
2
3
4
5
6
7
8
9
10

しかし、現在アクティブなインスタンスの動的なプロパティに値をバインドしたいときがあるかもしれません。それを実現するためにはv-bindを使用できます。さらに、v-bindを使用することで入力値に文字列以外の値もバインドできるようになります。

# チェックボックス

<input type="checkbox" v-model="toggle" true-value="yes" false-value="no" />
1
// チェックされているとき:
vm.toggle === 'yes'
// チェックされていないとき:
vm.toggle === 'no'
1
2
3
4

Tip

true-valuefalse-value 属性は input の value 属性には影響を及ぼしません。なぜならブラウザはチェックされていないチェックボックスをフォーム送信内容には含めないためです。二つの値(例: "yes" または "no")のうち一つが必ず送信されることを保証するには、代わりにラジオを使用してください。

# ラジオ

<input type="radio" v-model="pick" v-bind:value="a" />
1
// チェックされているとき:
vm.pick === vm.a
1
2

# セレクトオプション

<select v-model="selected">
  <!-- インラインオブジェクトリテラル -->
  <option :value="{ number: 123 }">123</option>
</select>
1
2
3
4
// 選択されているとき:
typeof vm.selected // => 'object'
vm.selected.number // => 123
1
2
3

# 修飾子

# .lazy

デフォルトではv-modelは各inputイベント後に入力値とデータを同期します(上述の IME 入力の例外はあります)。lazy 修飾子を加えることで、changeイベント後に同期するよう変更できます。

<!-- "input" ではなく "change" イベントの後に同期されます -->
<input v-model.lazy="msg" />
1
2

# .number

ユーザ入力を自動的に number へ型キャストさせたい場合は、v-modelで管理している input にnumber修飾子を加えることができます。

<input v-model.number="age" type="number" />
1

これはしばしば有用です。なぜならtype="number"が書いてあったとしても HTML の input 要素は常に文字列を返すためです。値がparseFloat() でパースできない場合は、元々の値が返却されます。

# .trim

ユーザ入力から空白を自動で取り除きたい場合は、v-modelで管理している input に trim 修飾子を加えることができます。

<input v-model.trim="msg" />
1

# コンポーネントのv-model

まだ Vue コンポーネントに慣れていない場合、この節は一旦スキップすることができます。

HTML 組み込みの input タイプが、常にあなたのニーズに適っているとは限りません。幸運にも、Vue コンポーネントによって、動作を隅々までカスタマイズ可能な再利用性のある入力フォームを自作することができます。それらのフォームにv-modelを使うことも可能です!詳しくは、コンポーネントガイドの カスタム input を参照してください。

Deployed on Netlify.
最終更新日: 10/8/2020, 11:37:48 PM