入力フィールド
テキストボックス
<input type="text" v-model="message">
<p>{{ message }}</p>
data() {
return {
message: 'test',
}
}
テキストエリア
<textarea v-model="message"></textarea>
<p>{{ message }}</p>
data() {
return {
message: 'test\ntest',
}
}
単体チェックボックス
<input type="checkbox" id="test-cb" v-model="checked">
<label for="test-cb">{{ checked ? "checked" : "unchecked" }}</label>
data() {
return {
checked: false,
}
}
複数チェックボックス
チェックするとlanguagesに対象のチェックボックスのvalueの値が格納され、
チェックを外すとlanguagesから対象のチェックボックスのvalueの値が削除される。
<input type="checkbox" id="javascript" value="JavaScript" v-model="languages">
<label for="javascript">JavaScript</label>
<input type="checkbox" id="golang" value="Go" v-model="languages">
<label for="golang">Go</label>
<input type="checkbox" id="ruby" value="Ruby" v-model="languages">
<label for="ruby">Ruby</label>
data() {
return {
languages: [],
}
}
ラジオボタン
<input type="radio" id="javascript" value="JavaScript" v-model="language">
<label for="javascript">JavaScript</label>
<input type="radio" id="golang" value="Go" v-model="language">
<label for="golang">Go</label>
<input type="radio" id="ruby" value="Ruby" v-model="language">
<label for="ruby">Ruby</label>
data() {
return {
language: '',
}
}
単体セレクトボックス
<select v-model="language">
<option disabled value="">Select language</option>
<option value="javascript">JavaScript</option>
<option value="golang">Go</option>
<option value="ruby">Ruby</option>
</select>
data() {
return {
language: '',
}
}
複数セレクトボックス
選択するとlanguagesに対象の選択肢のvalueの値が格納され、
選択を外すとlanguagesから対象の選択肢のvalueの値が削除される。
<select v-model="languages" multiple>
<option disabled value="">Select languages</option>
<option value="javascript">JavaScript</option>
<option value="golang">Go</option>
<option value="ruby">Ruby</option>
</select>
data() {
return {
languages: [],
}
}
修飾子
.lazy
データの同期を遅延する。
入力時には同期されず、enterキーやtabキー、他の要素をクリックするなどすると、データが同期される。
<input type="text" v-model.lazy="message">
<p>{{ message }}</p>
data() {
return {
message: 'test',
}
}
.number
入力値をNumberとして自動的に型変換してからデータを同期する。
inputのtypeにnumberを指定しても、常に文字列が返されるため、入力値をそのまま計算に使いたい時などに有用。
内部的にはparseFloat()を使っていて、変換できない場合は元の入力値が返される。
<input type="number" v-model.number="height">
<p>{{ height + 10 }}</p>
data() {
return {
height: 170,
}
}
.trim
入力値の前後の空白を除去してからデータを同期する。
全角でも半角でも除去される。
<input type="text" v-model.trim="message">
<p>{{ message }}</p>
data() {
return {
message: 'test',
}
}
カスタム入力
v-modelはコンポーネントに対しても利用することができる。
<custom-input v-model="message"></custom-input>
custom-inputのコードを書く前に、以下の2つのコードが同等であるということを理解する。
<input v-model="message">
<input :value="message" @input="message = $event.target.value">
データの単方向バインド(:value=”message”)とイベントをハンドルする処理(@input=”message = $event.target.value”)の組み合わせを、
双方向バインディング(v-model)が行っているということがわかる。
v-modelをコンポーネントに対して利用する場合、Vueは下記が同等となるように動作する。
<custom-input v-model="message"></custom-input>
<custom-input :value="message" @input="message = $event"></custom-input>
ここで大事になるのが、以下の2点である。
valueというpropsがcustom-inputに渡されている
inputイベントのハンドラは、$event.target.valueではなく$eventをバインドされているデータ(message)に代入している
すると、通常のフォーム入力バインディングと同じように動作するためには、下記のようにcustom-inputを実装する必要があるとわかる。
-
- propsのvalueをinput要素のvalueにバインドする(単方向バインディング)
inputイベントのハンドラで、inputイベントを入力値と共に親コンポーネントに通知する
var CustomInput = {
template: `<input :value="value" @input="$emit('input', $event.target.value)">`,
props: {
value: String
}
}
上記のように実装すると、本項の初めに書いたように
<custom-input v-model="message"></custom-input>
components: {
'custom-input': CustomInput
},
data() {
return {
message: 'test',
}
}
と利用することができる。