Vue-cli3を使ってポートフォリオを作ってGitHubPagesで公開する

フロントエンドの勉強を兼ねて、Vue.jsでポートフォリオを作成してみました。
Vue.jsを選んだ理由は特にないですが、初心者でも学習コストが低いと噂なのでVue.jsで開発してみることにしました。
まだまだ未完成では有りますがこんな感じです、
https://ryusukeeee.github.io/resume/

##はじめに
今回の開発で使用したVue.jsのバージョンはこちらです。

```sh
Vue CLI v3.5.1
```
その他、`vue-router`を使用して画面を複数に分けてよりシンプルなSPAを意識して作成しました。

##工夫した点
ポートフォリオ作成で主に工夫した箇所。
ありきたりではありますが、、、
###複数ページへのリンク
ポートフォリオのページを複数にして、各ページに遷移できるようにしたかったのでvue-routerを使用しました。
vue-cli3でプロジェクトを作成すると、追加するオプションを選択できるようになっているので便利です。

vue.jsのroute機能を設定するrouter.jsにリンク先のページを追加していきます。

```js:router.js
import Vue from 'vue'
import Router from 'vue-router'

Vue.use(Router)

export default new Router({
  mode: 'history',
  base: process.env.BASE_URL,
  routes: [
    {
      path: '/',
      name: 'home',
      component: () => import('./views/Home.vue')
    },
    {
      path: '/Skills',
      name: 'skills',
      component: () => import('./views/Skills.vue')
    },
    {
      path: '/Experience',
      name: 'experience',
      component: () => import('./views/Experience.vue')
    },
    {
      path: '/Works',
      name: 'works',
      component: () => import('./views/Works.vue')
    },
    {
      path: '/Posts',
      name: 'posts',
      component: () => import('./views/Posts.vue'),
    },
    {
      path: '*',
      name: 'home',
      component: () => import('./views/Home.vue')
    }
  ]
})
```
routeの設定はできたので次はリンクの作成ですが、全てのページにリンクのコードを描いていくのは非常に手間がかかるのでvue-componentを使用します。

```vue:src/components/myHeader.vue
<template>
  <nav class="profile-tab">
    <div class="profile-tab__wrap">
      <div class="profile-tab__list flex">
        <router-link to="/" class="profile-tab__link bold" exact-active-class="active">Home</router-link>
        <router-link to="/Skills" class="profile-tab__link bold" exact-active-class="active">Skills</router-link>
        <router-link to="/Experience" class="profile-tab__link bold" exact-active-class="active">Experience</router-link>
        <router-link to="/Works" class="profile-tab__link bold" exact-active-class="active">Works</router-link>
        <router-link to="/Posts" class="profile-tab__link bold" exact-active-class="active">Posts</router-link>
      </div>
    </div>
  </nav>
</template>
```
router-linkはvue-routerで使用できるコンポーネントで、クリックしたときにactiv要素が付与されるので便利でした。
[公式リファレンス](https://router.vuejs.org/ja/api/#router-link)

componentsができたのでApp.vue呼び出して各ページで表示されるようにします。

```vue:App.vue
<template>
  <div id="app">
    <my-header></my-header>
    <router-view/>
  </div>
</template>

<script>
import myHeader from './components/myHeader.vue'

export default {
  name: 'App',
  components: {
    myHeader
  }
}
</script>
```
作成したcomponentsを`myHeader`という名前でimportしてあげ、templateに追記します。
これで各ページを表示した際に、リンクのヘッダーが表示されるようになりました。

###外部APIと連携
axiosというJavaScriptのライブラリを使用すればHTTP通信を簡単に行なえて、外部APIでデータを取得できるようになるので今回のポートフォリオにも追加してみました。
axiosはオプションでの追加ではなくコマンドインストールするか、CDNを利用して使えるようにしなければなりません。
今回はnpmを使用してインストールしました

```sh
$ npm install --save-dev axios
```
ひとまずQiitaに投稿した内容をAPIで取得して、表示させてみる事にしました。

```vue:Posts.vue
<template>
  <section class='rsm-wrap-mg rsm-wrap rsm-wrap--post'>
    <h2 class="rsm-h center">Posts</h2>
    <div class="post__list relative flex flex-wrap space-between">
      <div class="post__card" v-for="post in posts_qiita">
        <div class="post-card__link">
          <a :href="post.url">{{post.title}}</a>
        </div>
        <div class="post-card__info">
          <div class="post-card__icon">
            <span class="post-card__like"><font-awesome-icon icon="thumbs-up" /></span>
            <span class="">{{post.likes_count}}</span>
          </div>
          <div>
            <span class="post-card__tag" v-for="tag in post.tags" :key="tag.name">{{tag.name}}</span>
          </div>
        </div>
      </div>
    </div>
  </section>
</template>

<script>
  import axios from 'axios'
  export default {
    name: 'Posts',
    data () {
      return {
        posts_qiita: []
      }
    },
    async created () {
      try {
        let res = await axios.get('https://qiita.com/api/v2/users/ryusukeeee/items')
        this.posts_qiita = res.data
      } catch (e) {
        console.error(e)
      }
    }
  }
</script>
```
vue.jsの`created`はインスタンスが生成された後に実行されるので、ページに遷移してきたらQiitaのAPIを使用して自分が投稿したデータを取得してきて`posts_qiita`に代入します。

表示には`v-for`を使用して、データを展開していき投稿した記事のタイトルといいねの数とタグを表示されるようにしました。
Qiitaの他にも自分がアウトプットしたものが増えていけばAPIでデータを取得して表示していきたいなと思ってます。
[公式リファレンス](https://jp.vuejs.org/v2/cookbook/using-axios-to-consume-apis.html)

##GitHubPagesへのホスティング
vue-cli3でプロジェクトを作成した場合は、プロジェクトのルートディレクトリに`vue.config.js`を作成する必要があるみたいです。

```js:vue.config.js
module.exports = {
  publicPath: process.env.NODE_ENV === 'production'
    ? '/resume/'
    : '/',
  outputDir: 'docs',
}
```
意味はこんな感じかと思います。
`publicPath`:アプリケーションがデプロイされるベースURL
`outputDir`:buildした際に生成されるディレクトリ
[公式リファレンス](https://cli.vuejs.org/config/#vue-config-js)

GitHubPagesでホスティングできるディレクトリは決まっているようで、`master`ブランチ直下か`master`ブランチの`docs/`配下しか内容なので、outputDirでdocsというディレクトリを生成するようにしました。
`npm run build`を実行してファイルを生成します。
GitHubにpushします。
対象のリポジトリのSettingsの「GitHub Pages」の「Source」を「master brunch /docs folder」に変更。
GitHubPagesのURLが表示されるので、完成です。

##まとめ
vue.jsとGitHubPagesを使ってSPAなポートフォリオが完成しました。
デザインの大部分は参考サイトがカッコよかったのでかなり参考にさせていただきました。（ほとんどと言ってもいいくらいです。。。）
もうちょっと作り込みたい感ありますので随時更新もしていこうかなと思います。

##参考
デザインの大部分を参考にさせていただきました。
https://www.resume.id/