jQueryとVue.jsの比較（表示・非表示＋コンポーネント）

今回はjQueryでもよくやる表示・非表示を切り替えるものをVue.jsでもやります。
また、コンポーネントの話にも進みたかったので今回はVue.jsのコンポーネントをCDN版のVue.jsで実施するという内容も含みます。


## 前回までの記事
- [jQueryとVue.jsの比較（入力バインディング編）](https://qiita.com/nori-shio88/items/7fc5eb5545292ed3e1ac)
- [jQueryとVue.jsの比較（算出プロパティ編）](https://qiita.com/nori-shio88/items/a9e09f2291805910e81b)

## 画面
![スクリーンショット 2020-02-01 22.49.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/26911/69e6bbaa-c314-d2e1-a497-3b1849bce9d2.png "スクリーンショット 2020-02-01 22.49.35.png")
![スクリーンショット 2020-02-01 22.54.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/26911/d8cebd36-f7d0-fbcd-a06d-660348d388fc.png "スクリーンショット 2020-02-01 22.54.24.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">
                <button class="btn btn-primary" id="toggleButton">非表示にする</button>
            </div>
            <h5 class="card-title">値を反映</h5>
            <div id="result">
                <p>表示中！！</p>
            </div>
        </div>
    </div>
</div>
```

`id="toggleButton"`とIDが振られた`button`を用意してます。
そのボタンが押されたら「表示する」⇔「非表示にする」を交互に入れ替えます。
また、`<div id="result">`内の文字列を「表示中！！」と無し状態を入れ替えます。

javascriptは以下の様にします。

```javascript
<script>
  $("#toggleButton").click(function() {
    if ($("#toggleButton").html() === "表示する") {
      $("#toggleButton").html("非表示にする");
      $("#result").append("<p>表示中！！</p>");
    } else {
      $("#toggleButton").html("表示する");
      $("#result").empty();
    }
  });
</script>
```
`$("#toggleButton").click()`でボタンがクリックされたイベントをトリガーに、現在ボタンの文字列が何になってるかを確認してボタンの表示内容と`<div id="result">`を切り替えるようにしています。

## 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">
                <button class="btn btn-primary" @click="toggle">
                    <div v-if="mode">
                        非表示にする
                    </div>
                    <div v-else>
                        表示する
                    </div>
                </button>
            </div>
            <h5 class="card-title">値を反映</h5>
            <div id="result">
                <result :mode="mode"></result>
            </div>
        </div>
    </div>
</div>
```

javascriptの部分は以下の通りです。

```javascript
<script>
    Vue.component('result', {
        props: {"mode": Boolean},
        template: `
            <p>{{ getDispValue }}</p>
        `,
        computed: {
            getDispValue: function(){
                if(this.mode){
                    return "表示中！！";
                }else{
                    return "";
                }
            }
        }
    });
    new Vue({
        el: "#vue",
        data: {
            mode: true
        },
        methods: {
            toggle(){
                this.mode = !this.mode;
            }
        }
    });
</script>
```

今回はVueのコンポーネントでテンプレートを作成しています。

```javascript
Vue.component('result', {
    props: {"mode": Boolean},
    template: `
        <p>{{ getDispValue }}</p>
    `,
    computed: {
        getDispValue: function(){
            if(this.mode){
                return "表示中！！";
            }else{
                return "";
            }
        }
    }
});
```

- `props`でコンポーネントが外部から値を受け取る値を指定
	- 今回は`mode`という表示を制御するBooleanを受け取ってます
- `template`がテンプレートの中身です
	- 今回は`<p>{{ getDispValue }}</p>`としてます
	- `{{}}`で囲う箇所はVueで値を埋め込む際のお約束です
- `computed`は[前回](https://qiita.com/nori-shio88/items/a9e09f2291805910e81b)登場した **算出プロパティ** です
	- `getDispValue`が`props`で受け取った`mode`から判断して「表示中！！」を返却するか空を返却するか行ってます

```javascript
new Vue({
    el: "#vue",
    data: {
        mode: true
    },
    methods: {
        toggle(){
            this.mode = !this.mode;
        }
    }
});
```

- Vueのインスタンスを作ってる箇所で
	- `data`に`mode`を持ってます
	- `methods`には`toggle()`という関数を持ってます
		- この`toggle()`はHTML側でボタンに`@click="toggle"`としてる箇所から呼ばれます

## まとめ
今回Vue側のコンポーネントは超ライトな内容にしてるのでコンポーネントのメリットは感じにくいかもしれないです。この程度であれば確かにjQueryで書いたほうが直感的にできてる気がします。ただ、コンポーネント化のメリットは繰り返し同じような表示を行う必要があるときに真価が発揮されるので、繰り返し同じようなボタン制御があるとjQueryの場合はボタンと表示領域のID管理が必要になってくるので重複コードが生まれやすいですが、Vueの場合はコンポーネント内に処理を内包できるのでメンテナンス性の向上も見込めるはずです。

### 補足
HTML5から`template`が追加されています。（[※参考](https://developer.mozilla.org/ja/docs/Web/HTML/Element/template)）
ただしIEはこの`template`に対応はしていないです。
だからVueのほうがいいのかというとIE11はES5までしか対応できてないのも事実です。（[※参考](https://kangax.github.io/compat-table/es5/)）
なのでIE11のように古いブラウザをサポートするのであればjavascriptの書き方をES5に合わせる、BabelやWebPackのようなトランスパイルを行うなどが必要になってきます。
開発する規模がどれくらいかによってjQueryのほうがいいかもしれないですし、サポートブラウザを明確にしてIE11を捨てるという方法がいいかもしれないですし、トランスパイルしてIE11サポートを頑張る方法もあると思います。


----
今回は以上です。