jQueryとVue.jsの比較（入力バインディング編）


jQueryで現状フロントの値の監視や操作、DOMの表示制御などを行ってる。
Vue.jsに置き換えるとイベント発火制御が少なくて済んだりコンポーネント化ができたりと、メリットあるなぁ〜というフンワリ理解してる部分を、実際に同じものをjQueryとVue.jsで作って違いを理解してみます。

今回は入力バインディング編です。



## 前提
Vue.jsはCDN版の方を使います。
jQueryについても同様にCDN版です。
  
```html
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" rel="stylesheet" />
<!-- jQuery + Popper.js + Bootstrap -->
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.bundle.min.js"></script>
<!-- Vue.js -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
```


※見た目を簡単にキレイにしたいのでBootstrapも使ってます。

## フォーム入力バインディング
`<input type="text">`で入力された値を`<p>`タグ内に同期で表示させるというシンプルなものです。
### 画面
![スクリーンショット 2020-01-25 22.59.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/26911/eb6b8a57-1b5a-7e0d-f372-885852057ce5.png "スクリーンショット 2020-01-25 22.59.25.png")

### jQueryの場合
HTMLのBODY部分は以下の通りです。

```html
<div class="container">
  <div class="mt-5"></div>
  <div class="card">
    <div class="card-header">
      jQueryの場合
    </div>
    <div class="card-body">
      <div class="form-group">
        <label for="text1">Text:</label>
        <input type="text" id="text1" class="form-control" value="hoge" />
      </div>
      <h5 class="card-title">値を反映</h5>
      <p class="card-text" id="result1"></p>
    </div>
  </div>
</div>
```

`input type="text"`の`#text1`に入力された値を`p`の`#result1`に反映させます。
まず初期値を反映させるために以下が必要です。

```javascript
$(function() {
	// 初期値反映
	$("#result1").html($("#text1").val());
});
```

そして、入力された値が変更されたことをトリガーにするのであれば以下のような`change`イベントトリガーでもいいのですが`change`イベントだと入力エリアからフォーカスが外れたときにしか発火されないので

```javascript
$("#text1").change(function() {
	// changeイベントだと入力エリアからフォーカスが外れたときにだけ発火
	$("#result1").html($(this).val());
});
```

今回は値の入力と同期させたいので`keyup`イベントトリガーが正しいです。

```javascript
$("#text1").keyup(function() {
	// keyupイベントは入力時にキーを離した瞬間に発火
	$("#result1").html($(this).val());
});
```
#### 結果
以下のような動きをする画面ができました。
![jquery.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/26911/60f48c43-3804-3c76-745a-c635f13682f1.gif "jquery.gif")

では次にVue.jsの場合です。

### Vue.jsの場合
HTMLのBODY部分は以下の通りです。

```html
<div class="container">
    <div class="mt-5"></div>
    <div class="card" id="vue">
	    <div class="card-header">
	        Vue.jsの場合
	    </div>
	    <div class="card-body">
	        <div class="form-group">
	        <label for="text2">Text:</label>
	        <input type="text" id="text2" class="form-control" v-model="result2"/>
	        </div>
	        <h5 class="card-title">値を反映</h5>
	        <p class="card-text" id="result2">{{ result2 }}</p>
	    </div>
    </div>
</div>
```
- `<div class="card" id="vue">`とVueが操作するエリアと指定させるために`id="vue"`としました
- `input`タグに`v-model="result2"`が追加されています。
- `p`タグには`{{ result2 }}`が追加されてます。

javascriptは何をするかというと以下のみです。

```javascript
new Vue({
    el: "#vue",
    data: {
        result2: "hoge"
    }
});
```
やっていることは以下のみです。
- `new Vue`でVueのインスタンスを作成
- `el`で固有のルートを指定（今回は`#vue`）
- `data`に`result2`を定義し、初期値に`"hoge"`を入れる

HTML部分と組み合わせると・・・

- `#vue`配下はVueで操作するエリアとして指定されて、`result2`というデータを持っている
- `input`タグに入力された値は`v-model`で`data`の`result2`に値を管理させるようにしている
- `{{ result2 }}`は`data`の`reslut2`を表示している

ということになります。

#### 結果
![vue.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/26911/2efc0438-1b96-2f4a-882e-10551947be9e.gif "vue.gif")


# まとめ
Vue.jsの入力バインディング１つとってもjQueryだと初期値を考慮して、イベントを監視して、イベント発火したら特定のタグ要素に値を反映して〜と、１つづつ明示的に指定していく必要がある印象です。
他にも色々と違いは出てくると思うのでネタが思いつき次第まとめていきます。

また、個人的にですがQiitaの投稿が久しぶりなので、リハビリ兼ねてライトな部分からですがjQueryよりVueのココがいいよって理解するためにも継続していけるようがんばります。

# 追記
[jQueryとVue.jsの比較（算出プロパティ編）](https://qiita.com/nori-shio88/items/a9e09f2291805910e81b)を書きました。