フォーム入力バインディング
フロントエンドでフォームを扱う場合、フォームの入力要素の状態と、対応する JavaScript の状態を同期しなければならないことがよくあります。値のバインディングやイベントリスナーの変更を手動で行うのは面倒です:
template
<input
:value="text"
@input="event => text = event.target.value">
v-model
ディレクティブは、上記を単純化するのに役立ちます:
template
<input v-model="text">
さらに、 v-model
は様々な種類の入力や <textarea>
、 <select>
要素の入力で使用することができます。使用する要素に応じて、異なる DOM プロパティとイベントのペアに自動で展開します:
- text 型の
<input>
と<textarea>
要素はvalue
プロパティとinput
イベントを使用します。 <input type="checkbox">
と<input type="radio">
はchecked
プロパティとchange
イベントを使用します。<select>
はvalue
props とchange
イベントを使用します。
Note
v-model
はフォーム要素にある value
、checked
、selected
属性の初期値を無視します。 v-model
は常に現在バインドされた JavaScript の状態を信頼できるソースとして扱います。初期値の宣言は JavaScript 側で、リアクティビティー API を使用して行ってください。
基本的な使い方
テキスト
template
<p>Message is: {{ message }}</p>
<input v-model="message" placeholder="edit me" />
Message is:
Note
IME を必要とする言語(中国語、日本語、韓国語など)では、IME による入力中に v-model
が更新されないことに気づくでしょう。 もしこれらの更新にも対応したい場合は、 v-model
の代わりに input
イベントリスナーと value
バインディングを使用してください。
複数行テキスト
template
<span>Multiline message is:</span>
<p style="white-space: pre-line;">{{ message }}</p>
<textarea v-model="message" placeholder="add multiple lines"></textarea>
Multiline message is:
<textarea>
内の補間は機能しないことに注意してください。代わりに v-model
を使用してください。
template
<!-- bad -->
<textarea>{{ text }}</textarea>
<!-- good -->
<textarea v-model="text"></textarea>
チェックボックス
単一のチェックボックス、真偽値:
template
<input type="checkbox" id="checkbox" v-model="checked" />
<label for="checkbox">{{ checked }}</label>
複数のチェックボックスを同じ配列もしくは Set の値にバインドすることもできます:
js
const checkedNames = ref([])
template
<div>Checked names: {{ checkedNames }}</div>
<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>
Checked names: []
この場合、 checkedNames
配列には現在チェックされているボックスの値が常に格納されます。
ラジオ
template
<div>Picked: {{ picked }}</div>
<input type="radio" id="one" value="One" v-model="picked" />
<label for="one">One</label>
<input type="radio" id="two" value="Two" v-model="picked" />
<label for="two">Two</label>
Picked:
セレクト
単一選択:
template
<div>Selected: {{ selected }}</div>
<select v-model="selected">
<option disabled value="">Please select one</option>
<option>A</option>
<option>B</option>
<option>C</option>
</select>
Selected:
注意
もし v-model
式の初期値がどのオプションにもマッチしない場合、 <select>
要素は "unselected" 状態でレンダリングされます。 iOS では、このような場合に change イベントが発火しないため、ユーザーは最初のアイテムを選択できないことになります。したがって、上記の例のように、空の値を持つ disabled オプションを提供することが推奨されます。
複数選択(配列へのバインド):
template
<div>Selected: {{ selected }}</div>
<select v-model="selected" multiple>
<option>A</option>
<option>B</option>
<option>C</option>
</select>
Selected: []
セレクトオプションは v-for
で動的にレンダリングすることができます:
js
const selected = ref('A')
const options = ref([
{ text: 'One', value: 'A' },
{ text: 'Two', value: 'B' },
{ text: 'Three', value: 'C' }
])
template
<select v-model="selected">
<option v-for="option in options" :value="option.value">
{{ option.text }}
</option>
</select>
<div>Selected: {{ selected }}</div>
値のバインディング
ラジオやチェックボックス、セレクトオプションにおいて、 v-model
でバインディングされる値は通常は静的な文字列です(またチェックボックスでは真偽値も):
template
<!-- チェックされているとき `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>
しかし時には現在アクティブなインスタンスの動的プロパティに値をバインドしたいことがあります。それには v-bind
を使用することができます。さらに、 v-bind
を使用することで文字列以外の値も入力値にバインドすることができます。
チェックボックス
template
<input
type="checkbox"
v-model="toggle"
true-value="yes"
false-value="no" />
true-value
と false-value
は v-model
においてのみ機能する Vue 特有の属性です。ここでは toggle
プロパティの値はボックスがチェックされると 'yes'
がセットされ、チェックが外されると 'no'
がセットされます。 v-bind
を使用して動的な値にバインドすることもできます。
template
<input
type="checkbox"
v-model="toggle"
:true-value="dynamicTrueValue"
:false-value="dynamicFalseValue" />
ヒント
ブラウザはチェックされていないボックスをフォームの送信には含めないため、 true-value
と false-value
属性は入力の value
属性に影響を与えません。 2 つの値(例、"yes" もしくは "no")のうち 1 つが送信されることを保証するには、代わりにラジオを使用してください。
ラジオ
template
<input type="radio" v-model="pick" :value="first" />
<input type="radio" v-model="pick" :value="second" />
pick
には、 1 つ目のラジオがチェックされると first
の値がセットされ、 2 つ目のラジオがチェックされると second
の値がセットされます。
セレクトオプション
template
<select v-model="selected">
<!-- インラインのオブジェクトリテラル -->
<option :value="{ number: 123 }">123</option>
</select>
v-model
は文字列でない値のバインディングもサポートしています! 上記の例では、オプションが選択されると、 selected
にはオブジェクトリテラル値である { number: 123 }
がセットされます。
修飾子
.lazy
デフォルトでは、 v-model
は各 input
イベントの後に、入力とデータを同期します(上記 の IME による入力は例外とします)。 代わりに change
イベント後に同期する lazy
修飾子を追加することができます。
template
<!-- "input" の代わりに "change" イベント後に同期されます -->
<input v-model.lazy="msg" />
.number
ユーザー入力を自動で数値として型変換したい場合、 v-model
で管理している入力に number
修飾子を追加することができます。
template
<input v-model.number="age" />
もし値が parseFloat()
で解析できない場合は、代わりに元の値が使用されます。
input が type="number"
を持つ場合は number
修飾子が自動で適用されます。
.trim
ユーザー入力から自動で空白を取り除きたい場合、 v-model
で管理している入力に trim
修飾子を追加することができます。
template
<input v-model.trim="msg" />
コンポーネントの v-model
Vue のコンポーネントにまだ慣れていない場合、とりあえずはこのセクションをスキップすることができます。
HTML 組み込みの input タイプが常にあなたのニーズを満たすとは限りません。幸いなことに、 Vue のコンポーネントでは完全にカスタマイズされた動作を持つ再利用可能な入力を構築することが可能です。それらの入力は v-model
でも動作します! 詳しくは、コンポーネントガイドの v-model
の使い方 を参照してください。