Vue.jsで、取得したJSONデータの配列を元に繰り返し描画する方法

プロトアウトスタジオGW短期講習2日目の成果です！

# やりたいこと
配列内の要素の数分、繰り返しオブジェクトを生成する

例えば、

```json

[{
ttl:'タイトルその1',
img:'画像URLその1',
desc:'説明文その1'
},
{
ttl:'タイトルその2',
img:'画像URLその2',
desc:'説明文その2'
},
{
ttl:'タイトルその3',
img:'画像URLその3',
desc:'説明文その3'
}
]

```


下記の様な構造で、タイトル文/画像URL/説明文をはめ込みたいとき...

```HTML
<h2>タイトルその1</h2>
<img src= "画像URLその1">
<p>説明文その1</p>

<h2>タイトルその2</h2>
<img src= "画像URLその2">
<p>説明文その2</p>
...

```

**全部ベタ書きするのは嫌だ！！！！！！**

# サンプル
直近打ち上げ予定のロケット情報を表示するWebサイト。
https://mizuki-kisa.github.io/protoout-lesson/
## 使った技術
- [Launch Library:ロケット打ち上げ情報についてのAPI](https://launchlibrary.net/docs/1.3/api.html)
- Vue.js

参考にしたサイト
https://programmingnavi.com/1874/

## 全文

```HTML:全文
<html>
  <head>
    <title>Hello My WebSite!</title>
    <link href="style2.css" rel="stylesheet">
  </head>
  <body>
    <h1>ROCKET</h1>
    <p>近々発射予定のロケット情報一覧</p>
    
    <div id="app">
        
        <div v-for='item in rockets'>
            <a v-bind:href="item.wikiURL" target="_blank" >
            <img v-bind:src="item.img">
            <h2>{{ item.name }}</h2>
            <h3>{{ item.agencie }}</h3>
            </a>
            <dl>
                <dt>Mission: {{item.missionttl}}</dt>
                <dd>{{item.missiondesc}}</dd>
            </dl>
        </div>
    
        
    </div>


    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
    <script>
    const app = new Vue({
            el: '#app',
            data: {
                rockets:[
                ],
            },

            methods: {
                getData: async function(){
                    const response = await axios.get('https://launchlibrary.net/1.3/launch/next/12')
                    console.log(response.data.launches);
                
                    response.data.launches.forEach(element => {
                        var agencie_ = 'none';
                        var mission_ = 'none';
                        var mission_desc = 'none';
                        (!element.rocket.agencies) ? agencie_ = 'none' : agencie_ = element.rocket.agencies[0].name;
                        (!element.missions[0]) ? mission_ = 'none' : (mission_ = element.missions[0].name, mission_desc = element.missions[0].description);

                        this.rockets.push({
                            name: element.name,
                            img: element.rocket.imageURL,
                            agencie: agencie_,
                            wikiURL: element.rocket.wikiURL,
                            missionttl: mission_,
                            missiondesc: mission_desc,
                        });
                    });

                },
            },

            mounted: function(){
                this.getData();
            }
        })
    </script>
  </body>
</html>
```


# 解説

## axiosを使ってAPIを叩く

```javascript
const response = await axios.get('https://launchlibrary.net/1.3/launch/next/12')
                    console.log(response.data.launches);
```

## レスポンスの中から、必要な情報を抽出し、dataに格納する

はじめはデータの中は空っぽです。

```javascript

data: {
                rockets:[
                ],
            },
```

rocketsに要素の数分配列を追加します。

```javascript
this.rockets.push({
  name: element.name,
  img: element.rocket.imageURL,
  agencie: agencie_,
  wikiURL: element.rocket.wikiURL,
  missionttl: mission_,
  missiondesc: mission_desc,
});
```

### 補足
missionとagencieはデータによっては存在せず、エラーが返ってきてしまうため、
存在する場合はデータを代入し、存在しない場合は'none'とするようにしています。

```javascript

var agencie_ = 'none';
  var mission_ = 'none';
  var mission_desc = 'none';
  (!element.rocket.agencies) ? agencie_ = 'none' : agencie_ = element.rocket.agencies[0].name;
  (!element.missions[0]) ? mission_ = 'none' : (mission_ = element.missions[0].name, mission_desc = element.missions[0].description);


```

## `v-for='item in items'` を使う
v-forはVue.jsのfor文的なものなのですね。
itemsは配列全体、itemは配列内の要素を指します。

今回、roketsの中身の数分繰り返したいため、

```
v-for='item in rokets'
```

としました。

item内の値には、`item.key名` でアクセスすることができます。
これで、divをdataの中身を代入しながら繰り返し描画することが可能になります。

```HTML
<div v-for='item in rockets'>
            <a v-bind:href="item.wikiURL" target="_blank" >
            <img v-bind:src="item.img">
            <h2>{{ item.name }}</h2>
            <h3>{{ item.agencie }}</h3>
            </a>
            <dl>
                <dt>Mission: {{item.missionttl}}</dt>
                <dd>{{item.missiondesc}}</dd>
            </dl>
        </div>
```

# 感想
この手の処理、今まではappendChildでやっておりましたが、Vue.jsを使うと文書構造とデータを分けてキレイに書けて良いですね！
マスターしたい！！