入力フィールド

テキストボックス

<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',
  }
}

と利用することができる。

bannerAds