Vue.jsを使ってみる

# はじめに
普段、フレームワークは特に使わず、jQueryを使って実装しています。
Vueがいいよとチームメンバーからおすすめされていたものの、いまいちピンと来ず、、、。
実際に使ってみたので、思ったことを書こうと思います。

## なぜ使おうと思ったのか
jsonファイルの中の要素分DOMの生成をする必要があった。
パフォーマンス的にappendは少ない回数の方がいいと言われているため、文字連結させて最後に出力したのだが、コードが長くなってしまった。
マークアップに修正があった場合、再度jsも書きなおす必要があるという指摘を受けた。
その時、Vueならとても楽であるというアドバイスを受け、実践してみることにした。

## 実装内容
下記json内容を全て反映させる。

```
{
  "matches": [
    {
      "date": "0714",
      "matches": [
        {
          "teamA": "1-1-A",
          "teamB": "1-1-B",
          "time": "12:00"
        }
      ]
    },
    {
      "date": "0715",
      "matches": [
        {
          "teamA": "2-1-A",
          "teamB": "2-1-B",
          "time": "11:00"
        },
        {
          "teamA": "2-2-A",
          "teamB": "2-2-B",
          "time": "13:00"
        },
        {
          "teamA": "2-3-A",
          "teamB": "2-3-B",
          "time": "15:00"
        }
      ]
    },
    {
      "date": "0716",
      "matches": [
        {
          "teamA": "3-1-A",
          "teamB": "3-1-B",
          "time": "10:00"
        },
        {
          "teamA": "3-2-A",
          "teamB": "3-2-B",
          "time": "12:00"
        },
        {
          "teamA": "3-3-A",
          "teamB": "3-3-B",
          "time": "14:00"
        },
        {
          "teamA": "3-4-A",
          "teamB": "3-4-B",
          "time": "16:00"
        }
      ]
    }
  ]
}

```
下記のような試合日程を出力するのが目標

<img width="257" alt="image1" src="https://qiita-image-store.s3.amazonaws.com/0/130667/509c4796-c631-838e-1a32-7f496a437a94.png">



## jQueryで実装
```html:index1.html
<ul class="match__list"></ul>
```

```javascript:index1.js
addDom() {
    const $matchList = $('.match__list');
    let htmlStrings = '';
    this.matchesData.matches.forEach(index => {
      this.setMatchDate(index);
      htmlStrings += `<li class="match__list__item"><div class="match__list__item__days">${this.getMatchDate(
        index.date
      )}</div><div class="match__info">${this.getMatchInfoBox(
        index,
        index.matches
      )}</div></div></li>`;
    });
    $matchList.append(htmlStrings);
  }

  getMatchDate(matchDate) {
    const matchMonth = matchDate.slice(5, 6);
    let matchDay = matchDate.slice(6, 8);
    if (matchDay.slice(0, 1) === '0') {
      matchDay = matchDate.slice(7, 8);
    }
    return `<p>${matchMonth}<span>/</span>${matchDay}</p>`;
  }

  getMatchInfoBox(matches, matchLength) {
    let htmlStrings = '';
    matchLength.forEach(index => {
      htmlStrings += `<div class="match__info__box"><p class="match__info__time">${
        index.time
      }</p><div class="match__info__box__match"><p>${
        index.teamA
      }<span class="match__vs">vs</span>${index.teamB}${this.getMatchInfoLimit(
        matches,
        index.limit
      )}</p></div></div>`;
    });
    return htmlStrings;
  }

```
※ファイル全体だと長くなるので、必要な部分だけ記載しています。

## Vue.jsで実装
```html:index2.html
<ul class="match__list" id="list">
<li class="match__list__item" v-for="item in search_list.matches">
    <div class="match__list__item__days">{{item.date}}</div>
    <div class="match__info">
        <div class="match__info__box" v-for="match in item.matches">
            <p class="match__info__time">{{match.time}}</p>
            <div class="match__info__box__match">
                <p>{{match.teamA}}
                    <span class="match__vs">vs</span>
                    {{match.teamB}}
                </p>
            </div>
        </div>
    </div>
</li>
</ul>
```

```javascript:index2.js
this.listItem = new Vue({
  el: '#list',
  data: {
    // Jsonデータ格納用
    search_list: []
  },
  created() {
    axios.get('./json/maches.json').then(response => {
      Vue.set(this, 'match', response.data);
      this.search_list = response.data;
    });
  }
});
```
※jsonの読み込みには[axios](https://www.npmjs.com/package/axios)を使用しています。

## 思ったこと
jQueryを使った時は、これ以上appendするコードが増えてしまったらさすがに面倒だなと思っていました。
また、マークアップに修正が必要な場合、jsも書きなおす必要があるので、手間がかかるなとも思っていました。
そのぶん、Vueを使うとjsのコード量もそこまで多くないですし、マークアップに修正があってもVueディレクティブを同じように入れておけばそれで済むので、とっても楽だなと思いました。

#終わりに
何をするにもVue最高！！とはまだ実感できていませんが、DOMの操作がある場合は非常に楽に実装できました。
実装内容に応じて、上手にVueを使っていきたいなと思います。