Vue.js　フォーム入力バインディング

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

前回の記事はこちら
[Vue.js イベントハンドリング](https://qiita.com/fumiya0414/items/dac76797939d0a3409bc)

##v-model利用時の属性について
v-modelを利用してデータバインディングした場合は
value,checked,selectedなどの属性は無視されます。

以下のコードで検証してみましょう
[jsfiddle](https://jsfiddle.net/)で実際に記述しながら読むことをおすすめします。

```html:index/html
<div id="app">

<p>
  {{message}}
</p>
<p>
  <input type="text" v-model="message"　value="hogehoge">
</p>

<pre>
  {{ $data }}
</pre>

</div>

<script src ="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
```

```javascript:index.js
var app = new Vue({
  el:'#app',
  data:{
    message:"Hello Vue.js"
  }
})
```
実行結果

[![Image from Gyazo](https://i.gyazo.com/ff114f21ba0c82a7f20a9ffc0e3b7a8a.png)](https://gyazo.com/ff114f21ba0c82a7f20a9ffc0e3b7a8a)

上記ではinputタグのvalueとして"hogehoge"を指定していますが
バインディングの結果value属性は無視されています。

##複数行テキスト
textareaではマスタッシュ構文{{}}を使ったデータバインディングは使えません。

```html:index/html
<div id="app">
<p>
  {{ message }}
</p>

<textarea>
  {{ message }}
</textarea>

<pre>
  {{ $data }}
</pre>

<script src ="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>

```

```javascript:index.js
var app = new Vue({
  el:'#app',
  data:{
    message:"Hello Vue.js"
  }
})
```
実行結果
[![Image from Gyazo](https://i.gyazo.com/de347ba96e037cc7097a94253df3f728.gif)](https://gyazo.com/de347ba96e037cc7097a94253df3f728)

テキストエリアではマスタッシュ構文は使えないため
入力した値は変わりません。

v-modelディレクティブを使用して書き直してみましょう。

```html:index/html
<div id="app">
<p>
  {{ message }}
</p>

<textarea v-model="message">
</textarea>

<pre>
  {{ $data }}
</pre>

<script src ="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
```

```javascript:index.js
var app = new Vue({
  el:'#app',
  data:{
    message:"Hello Vue.js"
  }
})
```

実行結果
[![Image from Gyazo](https://i.gyazo.com/d0ecf3713875113426c30047f755ae81.gif)](https://gyazo.com/d0ecf3713875113426c30047f755ae81)

双方向バインディングによってデータが同期されています。

##チェックボックス

チェックボックスはタイプによって以下となります。
単体チェックボックス　boolean値
複数チェックボックス　配列

###単体チェックボックス

チェックの有無でtrue/falseを切り替えてみましょう

```html:index/html
<div id="app">

  <input type="checkbox" id="checkbox" v-model="checked">
  <label for="checkbox">{{checked}}</label>
  <pre>{{ $data }}</pre>

</div>
<script src ="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
```

```javascript:index.js
var app = new Vue({
  el:'#app',
  data:{
    checked:false
  }
})
```
実行結果
[![Image from Gyazo](https://i.gyazo.com/8f8fcb1627fdce25f966b34a58000713.gif)](https://gyazo.com/8f8fcb1627fdce25f966b34a58000713)

##複数チェックボックス
```html:index/html
<div id="app">

<input type="checkbox" id="red" value="Red" v-model="colors">
<label for="red">Red</label>
<input type="checkbox" id="blue" value="Blue" v-model="colors">
<label for="red">Blue</label>
<input type="checkbox" id="green" value="Green" v-model="colors">
<label for="red">Green</label>

<p>
  {{colors}}
</p>

</div>
<script src ="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
```

```javascript:index.js
var app = new Vue({
  el:'#app',
  data:{
    colors:[],
  }
})
```
実行結果
[![Image from Gyazo](https://i.gyazo.com/c073bbafb0c416924fea54d94b6c853a.gif)](https://gyazo.com/c073bbafb0c416924fea54d94b6c853a)
チェックボックスで選択されたnameがv-modelディレクティブによって配列colorsに格納されます。

##ラジオボタン
ラジオボタンの場合は以下です。

```html:index/html
<div id="app">

<input type="radio" id="red" value="Red" v-model="color">
<label for="red">Red</label>
<input type="radio" id="green" value="Green" v-model="color">
<label for="green">Green</label>
<input type="radio" id="blue" value="Blue" v-model="color">
<label for="blue">Blue</label>

<p>
  {{color}}
</p>

</div>
<script src ="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
```

```javascript:index.js
var app = new Vue({
  el:'#app',
  data:{
    color:""
  }
})
```
実行結果
[![Image from Gyazo](https://i.gyazo.com/3517af5780577f675a479757877633b3.gif)](https://gyazo.com/3517af5780577f675a479757877633b3)

選択の結果は１つなのでdataオプションのプロパティ名もcolorと単数にしています。

##セレクトボックス（単体の選択）
セレクトボックスの場合は以下のように記述します

```html:index/html
<div id="app">

<select name="" v-model="selected">
<option disabled value="">Please select one</option>
　<option>Red</option>
　<option>Green</option>
　<option>Blue</option>
</select>

<p>
  {{ selected }}
</p>


</div>
<script src ="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
```

```javascript:index.js
var app = new Vue({
  el:'#app',
  data:{
    selected:""
  }
})
```
実行結果
[![Image from Gyazo](https://i.gyazo.com/2a154b60843972975944e325aeb9f9e2.gif)](https://gyazo.com/2a154b60843972975944e325aeb9f9e2)

初期値のPlease select oneは選択できないようにしておきましょう

##セレクトボックス（複数の選択）
複数選択の場合はプロパティのデフォルト値を配列にしましょう

```html:index/html
<div id="app">

<select name="" v-model="selected" multiple>
<option disabled value="">Please select one</option>
<option>Red</option>
<option>Green</option>
<option>Blue</option>
</select>

<p>
  {{ selected }}
</p>


</div>
<script src ="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
```

```javascript:index.js
var app = new Vue({
  el:'#app',
  data:{
    selected:[]
    
  }
})
```

実行結果
[![Image from Gyazo](https://i.gyazo.com/a65b0f5b6986374f8a6b12db5632821a.gif)](https://gyazo.com/a65b0f5b6986374f8a6b12db5632821a)

シフトキーを押しながら選択することで複数選択を可能にし配列に格納しています。

##フォーム入力バインディングの修飾子
フォーム入力バインディングの代表的な修飾子は以下です。

.lazy　バインドのタイミングを遅延させる
.trim　入力前後の空白を取り除いてデータに代入
.number　入力値を数値型に変換してから代入

###修飾子.lazy
修飾子.lazyで入力確定後のバインディングを実装することができます。

.lazyなし
[![Image from Gyazo](https://i.gyazo.com/df21731423c35735c7c14aba2880cb84.gif)](https://gyazo.com/df21731423c35735c7c14aba2880cb84)
１文字ずつバインディングされてしまいます

.lazyあり
[![Image from Gyazo](https://i.gyazo.com/748e98b3c508556d9239493e129f2430.gif)](https://gyazo.com/748e98b3c508556d9239493e129f2430)
エンターキーで確定したタイミングでバインディングされます。

コードの記述は以下です。

```html:index/html
<div id="app">

<p>
  <input type="text" v-model.lazy="message">
</p>

<p>
  {{message}}
</p>

</div>
<script src ="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
```

```javascript:index.js
var app = new Vue({
  el:'#app',
  data:{
    message:""
  }
})
```

v-modelディレクティブの末尾に.lazyと追記しています。

###修飾子.trim

修飾子.trimでinputされたデータの前後の空白（space）を取り除くことができます

.trimなし
[![Image from Gyazo](https://i.gyazo.com/ef2ccf45d78d986fdcc9964178021fe7.gif)](https://gyazo.com/ef2ccf45d78d986fdcc9964178021fe7)
abcの前後に半角スペースを５個入れています。

.trimあり
[![Image from Gyazo](https://i.gyazo.com/3506cbc95b1bac6cad6a47d6b16f1558.gif)](https://gyazo.com/3506cbc95b1bac6cad6a47d6b16f1558)

コードの記述は以下です。
```html:index/html
<div id="app">
<p>
  <input type="text" v-model.trim="message">
</p>

<p>
  <input type="text" v-model="message">
</p>

<pre>
  {{$data}}
</pre>

</div>
<script src ="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
```

```javascript:index.js
var app = new Vue({
  el:'#app',
  data:{
    message:""
  }
})
```
全角のスペースも取り除くことができます。

###修飾子.number
.number修飾子は入力値を数値型に型変換してからデータに代入します。

ユーザー入力の値に+10するプログラムを記述しましょう
まずは以下を記述します

```html:index/html
<div id="app">
<p>
  <input type="number" v-model="age">
</p>
<p>
  {{ age + 10}}
</p>

</div>
<script src ="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
```

```javascript:index.js
var app = new Vue({
  el:'#app',
  data:{
    age:0
  }
})
```
実行結果
[![Image from Gyazo](https://i.gyazo.com/ce2ffcff0ea4fdee012282c270165482.gif)](https://gyazo.com/ce2ffcff0ea4fdee012282c270165482)
htmlのinput要素のはvalueはtype属性にnumberを使用しても文字列と認識されます。

以下のように.numberを追記します

```html
<input type="number" v-model.number="age">
```

実行結果
[![Image from Gyazo](https://i.gyazo.com/1a89966b2f23c4d33bce513f879ff562.gif)](https://gyazo.com/1a89966b2f23c4d33bce513f879ff562)

計算結果が正しく取得されるようになりました。

次回はコンポーネントです。
[Vue.js　コンポーネント](https://qiita.com/fumiya0414/items/84c677f256276aa99bf5)