Vue.jsのフォーム入力バインディングを勉強する

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

## 基本的な使い方
formのinput要素やtextarea要素、select要素に双方向(two-way)データバインディングを作成するには、**v-model**ディレクティブを使用する事ができます。
**v-model**は、自動的に入力要素のタイプに基いて要素を更新するための方法です。
**v-model**はユーザの入力イベントにおいてデータを更新するための基本的なお砂糖構文(syntax sugar)で、それに加えて、いくつかのエッジケースに対しては特別な配慮をしてくれます。

**<font color="red">【注意】</font>**
>**v-model**は任意のform要素にある**value**、**checked**または、**selected**属性の初期値を無視します。
**input**または**textarea**は常に信頼できる情報としてVueインスタンスを扱います。
コンポーネントのdataオプションで初期値を宣言する必要があります。

**v-model**は、内部的にはinput要素に応じて異なるプロパティを使用し、異なるイベントを使用する。

選択フィールドは、**value**プロパティとchangeイベントを使用します。

**<font color="red">【注意】</font>**
>IME(中国語、日本語、韓国語、その他)が必須な言語において、**v-model**ではIMEでテキストが確定するまでは更新されないことに注意してください。これからの更新に対して対応した場合は、**input**イベントを代わりに使用します。

## テキスト・複数行テキスト
テキストと複数行テキストは、**value**プロパティと**input**イベントを使用します。
```html
<div id="example">
  <input v-model="message" placeholder="テキストを入力">
  <p>テキスト：{{ message }}</p>

  <textarea v-model="comment" placeholder="複数行テキストを入力"></textarea>
  <p>複数行テキスト：</p>
  <p style="white-space: pre-line">{{ comment }}</p>
</div>
```

```javascript
let app = new Vue({
  el: '#example',
  data() {
    return {
      message: '',
      comment: ''
    }
  }
})
```

**v-model**で使用したdataプロパティにあらかじめ値をセットしておくことでテキストや複数行テキストにテキストを挿入しておくことができます。

## チェックボックス
単体のチェックボックスは、boolean値です。
チェックボックスは、checkedプロパティとchangeイベントを使用します。
```html
<div id="example">
  <input type="checkbox" id="checkbox" v-model="checked">
  <label for="checkbox">{{ checked }}</label>
</div>
```

```javascript
let app = new Vue({
  el: '#example',
  data() {
    return {
      checked: false
    }
  }
})
```

複数のチェックボックスは、同じ配列に束縛します。

```html
<div id="example">
  <input type="checkbox" id="apple" value="りんご" v-model="fruits">
  <label for="apple">りんご</label>
  <input type="checkbox" id="banana" value="バナナ" v-model="fruits">
  <label for="banana">バナナ</label>
  <input type="checkbox" id="pineapple" value="パイナップル" v-model="fruits">
  <label for="pineapple">パイナップル</label>
  <input type="checkbox" id="peach" value="桃" v-model="fruits">
  <label for="peach">桃</label>

  <p>選択したフルーツ：{{ fruits }}</p>
</div>
```

```javascript
let app = new Vue({
  el: '#example',
  data() {
    return {
      fruits: []
    }
  },
})
```

## ラジオボタン
```html
<div id="example">
  <input type="radio" id="male" value="男性" v-model="gender">
  <label for="one">男性</label>
  <br>
  <input type="radio" id="female" value="女性" v-model="gender">
  <label for="two">女性</label>
  <br>
  <p>性別：{{ gender }}</p>
</div>
```

```javascript
let app = new Vue({
  el: '#example',
  data() {
    return {
      gender:''
    }
  },
})
```

## 選択
```html
<div id="example">
  <select v-model="selected">
    <option disabled value="">選択してください</option>
    <option>斎藤工</option>
    <option>福山雅治</option>
    <option>木村拓哉</option>
  </select>
  <br>
  <span>抱かれたい男: {{ selected }}</span>
</div>
```

```javascript
let app = new Vue({
  el: '#example',
  data() {
    return {
      selected:''
    }
  },
})
```

### 複数選択（配列に束縛）

selectのmultipleを使い複数選択可能にし
選択されたオプションは配列に束縛する

```html
<div id="example">
  <select v-model="selected" multiple>
    <option disabled value="">選択してください</option>
    <option>斎藤工</option>
    <option>福山雅治</option>
    <option>木村拓哉</option>
  </select>
  <br>
  <p>複数選択可(shift + クリック)</p>
  <span>抱かれたい男: {{ selected }}</span>
</div>
```

```javascript
let app = new Vue({
  el: '#example',
  data() {
    return {
      selected:[]
    }
  },
})
```

### 動的オプションはv-forで描画できる

```html
<div id="example">
  <select v-model="selected">
    <option disabled value="">選択してください</option>
    <option v-for="option in options" v-bind:value="option.value">
      {{ option.text }}
    </option>
  </select>
  <br>
  <span>抱かれたい男: {{ selected }}</span>
</div>
```

```javascript
let app = new Vue({
  el: '#example',
  data() {
    return {
      selected: '',
      options: [
        { text: '斎藤工', value: '斎藤工' },
        { text: '福山雅治', value: '福山雅治' },
        { text: '木村拓哉', value: '木村拓哉' }
      ]
    }
  },
})
```

##　値のバインディング
**v-model**でバインディングされる値は通常は静的な文字列(チェックボックスならboolean)です

### チェックボックス
**true-value**属性:trueだった場合にtoggleに「同意しました」で更新**false-value**属性:falseだった場合にtoggleに「同意してません」で更新

```html
<div id="example">
  <input
    type="checkbox"
    v-model="toggle"
    true-value="同意しました"
    false-value="同意してません"
    id="check"
  >
  <label for="check">利用同意</label>
  <p>{{ toggle }}</p>
</div>
```

```javascript
let app = new Vue({
  el: '#example',
  data() {
    return {
      toggle: ''
    }
  },
})
```
**<font color="red">【注意】</font>**
> **true-value**と**false-value**属性は入力フォームのvalue属性には影響を及ぼしません。
なぜならブラウザはフォームの送信の中にチェックされていないチェックボックスを含めないからです。
2つの値(たとえば”同意しました”/“同意してません”)のどちらかが必ずフォームで送信されることを保証するには、代わりにラジオを使用してください。

## ラジオボタン

```html
<div id="example">
  <input type="radio" id="male" v-model="gender" v-bind:value="male">
  <label for="male">男性</label>
  <br>
  <input type="radio" id="female" v-model="gender" v-bind:value="female">
  <label for="female">女性</label>
  <br>
  <p>性別 v-model：{{ gender }}</p>
</div>
```

```javascript
let app = new Vue({
  el: '#example',
  data() {
    return {
      gender:'',
      male: '男性',
      female: '女性'
    }
  },
})
```

ラジオボタンがチェックされた時、値は下記のようになります。

```javascript
// 男性をチェックした場合
app.gender === app.male

// 女性をチェックした場合
app.gender === app.femaile
```

### 選択オプション

```html
<div id="example">
  <select v-model="selected">
    <option disabled value="">選択してください</option>
    <option v-bind:value="{name:'斎藤工', age:38}">斎藤工</option>
    <option v-bind:value="{name:'福山雅治', age:49}">福山雅治</option>
    <option v-bind:value="{name:'木村拓哉', age:45}">木村拓哉</option>
  </select>
  <br>
  <span>抱かれたい男 名前: {{ selected.name }}</span>
  <br>
  <span>抱かれたい男 歳: {{ selected.age }}</span>
</div>
```

```javascript
let app = new Vue({
  el: '#example',
  data() {
    return {
      selected:{}
    }
  },
})
```

## 修飾子

### .lazy
デフォルトでは、**v-model**は各**input**イベント（IME確定前を除く）の後に、データと入力を同期します。
**change**イベント後に同期したい場合に**lazy**修飾子を追加する。

```html
<div id="example">
  <div>メッセージ入力：<input v-model.lazy="message"></div>
  <p>入力が確定した時点で表示</p>
  <p>メッセージ表示：{{ message }}</p>
</div>
```

```javascript
let app = new Vue({
  el: '#example',
  data() {
    return {
      message:''
    }
  },
})
```

### .number
ユーザの入力を数値として自動的に型変換したいとき、**v-model**で束縛した入力に**number**を追加する

```html
<div id="example">
  <div>年齢入力(文字列型)：<input v-model="age" type="number"></div>
  <div>年齢入力(数値型)：<input v-model.number="age" type="number"></div>
  <p>年齢表示：{{ age }}</p>
  <p>年齢表示：{{ typeof age }}</p>
</div>
```

```javascript
let app = new Vue({
  el: '#example',
  data() {
    return {
      age: null
    }
  },
})
```

### .trim
ユーザの入力から空白を自動的に取り除きたいときは、 **v-model**に束縛された入力に**trim**を追加する

```html
<div id="example">
  <div>メッセージ入力：<input v-model.trim="message"></div>
  <p>メッセージ表示：{{ message }}</p>
</div>
```

```javascript
let app = new Vue({
  el: '#example',
  data() {
    return {
      message:''
    }
  },
})
```

## あとがき
コードを書いて理解してくださいとう表記が多くなってしまった感じもします。
入力フォームはhtmlの入力ホームに一手間加えるだけですので、慣れてしまえば難しいことはないと思います。

## 参考資料

[公式リファレンス](https://jp.vuejs.org/v2/guide/forms.html)