vue.js
Netlify
nuxt.js

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

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

今回もNetlifyにホスティングしました。
Collect-Vue
※ネーミングセンスないのでこの名前です。。。

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

Qiita API

Qiita API v2ドキュメントにエンドポイント等の
詳細な仕様は記載されているのでこちらを参照してみてください。

準備 + APIコール

axiosを使ってAPI呼び出ししました。

axiosのインストール

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

$ yarn add @nuxtjs/axios

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

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

フォルダ構成


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

APIコール

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で取得したレスポンスを1記事ごとにCardItemというコンポーネントに渡して
表示しています。

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>
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プロパティにアクセスできず断念しました。

あとがき

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