自分の為のまとめサイトをNetlifyにNuxtで作って公開した

VueとNuxtの纏めサイトを自分の為に作ってみました。
と言ってもまだ公式ページへのリンクとQiitaの投稿一覧が見れるだけなのですが・・・
これからもっと改良していく予定です。

今回もNetlifyにホスティングしました。
[Collect-Vue](https://laughing-kare-9118e3.netlify.com/)
※ネーミングセンスないのでこの名前です。。。

今回はQiita APIを使って投稿一覧を表示するところの実装を紹介します。

# Qiita API
[Qiita API v2ドキュメント](https://qiita.com/api/v2/docs)にエンドポイント等の
詳細な仕様は記載されているのでこちらを参照してみてください。

# 準備 + APIコール
axiosを使ってAPI呼び出ししました。

## axiosのインストール
準備としてaxiosをNuxtモジュールとしてインストールします。

```terminal
$ yarn add @nuxtjs/axios
```

インストールが完了したら`nuxt.config.js`に以下の設定を追記します。

```javascript
module.exports = {
  // 省略
  modules: [
    '@nuxtjs/axios'
  ]
  // 省略
}

```

## フォルダ構成

```terminal

collect_vue::
├─.nuxt
├─assets
├─components
│  └─Qiita
│     └─CardItem.vue
├─layouts
├─middleware
├─pages
│  └─qiita.vue
├─plugins
├─static
├─store

```

## APIコール

```javascript:qiita.vue
import axios from 'axios'
import CardlItem from '~/components/Qiita/CardItem.vue'
const BASE_URL = 'https://qiita.com/api/v2/tags/'

export default {
    components: {
        CardlItem
    },
    data () {
        return {
            tag: '',  // 検索時にリクエストに含めるタグ
            postList: []  // APIレスポンスを格納する器
        }
    },
    created () {
        // 初回ページ描画時にキーワード「nuxt.js」でQiitaのAPIをコール
        this.tag = 'nuxt.js'
        this.sendRequest(this.tag, 1)
    },
    methods: {
        search (tag, page) {
            this.sendRequest(tag, page)
        },
        // リクエスト送信
        sendRequest (tag, page) {
            axios.get(BASE_URL + tag + '/items', {
                headers: {'Content-Type': 'application/json'},
                params: {
                  page: page,   // ページ番号
                  per_page: 15  // ページあたりの記事数
                }
            })
            .then(response => {
                this.postList = response.data
            })
            .catch(e => {
                console.error('error:', e)
            })
        }
    }
}
```

これでタグごとの投稿一覧を取得できるのであとは表示するだけです。
APIで取得したレスポンスを１記事ごとに`CardItem`というコンポーネントに渡して
表示しています。

```html:qiita.vue
<template>
    <div>
        <div class="columns card-item-margin">
            <div class="column is-2"></div>
            <div class="column is-8">
                <form>
                    <span @click="search('Vue.js', '1')" class="tag is-primary is-large search-tag">Vue</span>
                    <span @click="search('Vuex', '1')" class="tag is-primary is-large search-tag">Vuex</span>
                    <span @click="search('Nuxt.js', '1')" class="tag is-primary is-large search-tag">Nuxt</span>
                </form>
            </div>
            <div class="column is-2"></div>
        </div>
        <div class="columns card-item-margin">
            <div class="column is-2"></div>
            <div class="column is-8">
                <!-- postListをグルグルす -->
                <div class="search-result" v-for="item in postList" :key="item.id">
                    <a v-bind:href="item.url" target="_blank">
                        <!-- CardItemにitemを渡して子コンポーネトで表示 -->
                        <CardlItem class="card-item" :item="item"></CardlItem>
                    </a>
                </div>
            </div>
            <div class="column is-2"></div>
        </div>
    </div>
</template>
```

```vue:CardItem.vue
<template>
    <div class="card">
        <time class="created-at"><i class="far fa-calendar-minus"></i>{{ item.created_at.replace('T', ' ').replace('+09:00', '') }}</time>
        <div class="card-content">
            <div class="media">
            <div class="media-left">
                <figure class="image is-64x64">
                <img :src="item.user.profile_image_url" alt="Placeholder image">
                </figure>
            </div>
            <div class="media-content">
                <p class="title is-4 qiita-title">{{ item.title }}</p>
                <div class="tags">
                    <span v-for="tag in item.tags" :key="tag.name" class="tag is-primary">{{ tag.name }}</span>
                </div>
            </div>
            </div>

            <div class="content">
                <div>
                    <i class="far fa-thumbs-up"> {{ item.likes_count }}</i>
                    <i class="far fa-comment"> {{ item.comments_count }}</i>
                </div>
            </div>
        </div>
    </div>
</template>

<script>
  export default {
    props: ['item']
  }
</script>

```

## 詰まったとこ
本当はページネーションを用意してページ遷移させたかったのですが、レスポンスヘッダーの
Linkプロパティにアクセスできず断念しました。

# あとがき
これから色々機能開発していく予定なので追加開発できたらまた紹介できればと思ってます。
色々ご意見頂ければ幸いです。