Nuxt.js + Vuetify + Netlify でポートフォリオサイトを作ってみた

## 動機

私自身、普段はRuby on Railsでシステムを開発していることもあって、なかなかフロントエンドのモダンなフレームワークに触る機会がありません。

そんな中、ちょうど[弊社](https://fusic.co.jp/)の開発合宿の時期が来たので
Nuxt.jsを使って練習がてら自分のポートフォリオサイトを作ることにしました。

予定していたページを全て完成させることはできませんでしたが、取り組んだ内容をまとめます。

### 作ったページ

https://portfolio.y-uuu.net/

<a href="https://portfolio.y-uuu.net/"><img width="1439" alt="yuuu_s_portfolio_と_profile_vue_—_yuuu_portfolio.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60996/ebba5147-ad29-bdb4-4edc-eb6616aaa47b.png"></a>

### リポジトリ

https://github.com/yuuu/yuuu_portfolio

## プロジェクト作成

`create-nuxt-app` を使ってnuxtプロジェクトを作る

```sh
$ npx create-nuxt-app yuuu_portfolio                                                                                                     [~/Documents/develop]
npx: 379個のパッケージを29.271秒でインストールしました。
> Generating Nuxt.js project in /Users/yokazaki/Documents/develop/yuuu_portfolio
? Project name yuuu_portfolio
? Project description yuuu's portfolio web site.
? Use a custom server framework none
? Choose features to install Progressive Web App (PWA) Support, Linter / Formatter, Prettier
? Use a custom UI framework vuetify
? Use a custom test framework none
? Choose rendering mode Universal
? Author name Yuhei Okazaki
? Choose a package manager yarn
```

さっそく起動してみる

```sh
$ cd yuuu_portfolio
$ yarn run dev
```

リポジトリを作ってgithubへpush

```sh
$ git remote add origin git@github.com:yuuu/yuuu_portfolio.git
$ git push -u origin master
```

リポジトリは以下
https://github.com/yuuu/yuuu_portfolio](https://github.com/yuuu/yuuu_portfolio

早速アクセスしてみると、既にVuetifyのレイアウトが一通り当たっていて感動。
http://localhost:3000/　
<img width="1439" alt="yuuu_portfolio.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60996/525e35a9-bec1-5743-0cff-1fcf8a7268af.png">

## Netlifyへデプロイしてみる

https://www.netlify.com/ へアクセスして、Sign upする
今回は、githubアカウントでログインすることに

ログインしたら `New site from Git` をクリック
<img width="1439" alt="Sites___Yuhei_Okazaki_s_team.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60996/2d0b1a86-0234-dfcf-a2f6-fa773433e29e.png">

githubにpushしたときに自動デプロイしたいので、 `Github` をクリック
<img width="1439" alt="Banners_and_Alerts_と_Create_a_new_site___Netlify.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60996/e09bffbb-00ee-e11d-51a6-15040bde5ab4.png">

github側で諸々認証すると、リポジトリを選択できるようになる
<img width="1439" alt="Create_a_new_site___Netlify.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60996/b7b11049-2a7e-332e-d905-8b15a4ab9309.png">

デプロイの設定を記載し、 `Deploy site` をクリック
<img width="1439" alt="Create_a_new_site___Netlify.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60996/efeb2d54-b6b9-3f4a-e27f-a541c5bedb4d.png">

デプロイが完了すると、URLが表示され、サイトを確認できる。
https://blissful-neumann-f43d8f.netlify.com/

## 独自ドメインをあてる
DNSサーバの変更が反映されるまでに若干時間がかかるので先にやっておく
<img width="1438" alt="Add_a_custom_domain_to_your_site___blissful-neumann-f43d8f.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60996/3b6af97b-9af3-23fa-cbe8-449e42e39c61.png">
<img width="1437" alt="Add_a_custom_domain_to_your_site___blissful-neumann-f43d8f.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60996/9992a564-e0b4-5fdb-c57f-5aa72a1de24f.png">

`Check DNS configuration` をクリックすると設定方法が提示されるので、自分のDNSサーバへ設定する
<img width="1438" alt="Domain_management___Settings.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60996/6764b8c1-4c2c-7f38-9405-609b8ba94e7b.png">

DNSの設定が通ったら、SSL証明書を発行する
<img width="1438" alt="Domain_management___Settings.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60996/922caa58-84ea-c6b5-c76b-ab5c4164b8d3.png">

## Vuetifyをカスタマイズ

### ベースカラーを変更

`plugins/vuetify.js` を編集する
`nuxt.config.js` に追記すると書かれている記事も見かけるが、こちらではないので要注意。

```js

import Vue from 'vue'
import Vuetify from 'vuetify/lib'
import colors from 'vuetify/es5/util/colors'

Vue.use(Vuetify, {
  theme: {
    primary: '#252a34',
    secondary: '#08d9d6',
    accent: '#ff2e63',
    info: colors.teal.lighten1,
    warning: colors.amber.base,
    error: colors.deepOrange.accent4,
    success: colors.green.accent3
  }
})
```

### レイアウトを変更

主にツールバーをカスタマイズ

`default.vue`

```vue
<template>
  <v-app>
    <v-navigation-drawer
      v-model="drawer"
      :clipped="clipped"
      fixed
      app
      class="hidden-md-and-up"
    >
      <v-list>
        <v-list-tile
          v-for="(item, i) in items"
          :key="i"
          :to="item.to"
          router
          exact
        >
          <v-list-tile-action>
            <v-layout justify-center>
              <font-awesome-icon :icon="item.icon" style="font-size: 30px;" />
            </v-layout>
          </v-list-tile-action>
          <v-list-tile-content>
            <v-list-tile-title v-text="item.title" />
          </v-list-tile-content>
        </v-list-tile>
      </v-list>
    </v-navigation-drawer>
    <v-toolbar color="primary" fixed app dark>
      <v-toolbar-side-icon class="hidden-md-and-up" @click="drawer = !drawer" />
      <v-btn icon active-class :to="'/'" color="grey lighten-3">
        <v-img src="/logo.png" aspect-ratio="1" />
      </v-btn>
      <v-toolbar-title to="/" v-text="title" />
      <v-spacer />
      <v-spacer></v-spacer>
      <v-toolbar-items class="hidden-sm-and-down">
        <v-btn v-for="(item, i) in items" :key="i" :to="item.to" flat>
          {{ item.title }}
        </v-btn>
      </v-toolbar-items>
    </v-toolbar>
    <v-content>
      <v-container grid-list-md>
        <transition name="fade">
          <nuxt />
        </transition>
      </v-container>
    </v-content>
    <v-footer :fixed="true" color="primary" dark app>
      <v-layout justify-center>
        <span>&copy; 2019 Yuhei Okazaki. All Rights Reserved.</span>
      </v-layout>
    </v-footer>
  </v-app>
</template>

<script>
import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome'

export default {
  components: {
    FontAwesomeIcon
  },
  data() {
    return {
      clipped: false,
      drawer: false,
      items: [
        { icon: ['fas', 'user-circle'], title: 'Profile', to: '/profile' },
        { icon: ['fas', 'laptop'], title: 'Works', to: '/works' },
        { icon: ['fas', 'wrench'], title: 'Languages', to: '/languages' },
        { icon: ['fas', 'toolbox'], title: 'Skills', to: '/skills' },
        { icon: ['fas', 'users'], title: 'Community', to: '/community' },
        { icon: ['fas', 'envelope'], title: 'Contact', to: '/contact' }
      ],
      title: "yuuu's portfolio"
    }
  }
}
</script>

<style>
.fade-enter-active,
.fade-leave-active {
  transition: opacity 1s;
}
.fade-enter, .fade-leave-to /* .fade-leave-active below version 2.1.8 */ {
  opacity: 0;
}
</style>

```

TOPページのコンテンツを作成

```vue
<template>
  <v-layout row wrap justify-center align-center>
    <v-flex sm6 md6>
      <div class="display-3">
        Welcome to yuuu&#39;s Portfolio.
      </div>
      <v-divider class="my-3"></v-divider>
      <div class="title mb-3">Check out my profile!</div>
      <v-layout justify-center>
        <v-btn color="secondary" large to="/profile">profile</v-btn>
      </v-layout>
    </v-flex>
    <v-flex sm6 md6>
      <v-img src="/logo.png" aspect-ratio="1" />
    </v-flex>
  </v-layout>
</template>
```

## Pull Request作成＆マージ

上記変更をgithubへpushしてPull Requestを作成すると、Netlifyがビルドを開始する
masterにマージせずともPull Requestの段階で、プレビューを表示でき、とても便利

<img width="1439" alt="ツールバーおよびTOPページレイアウト_by_yuuu_·_Pull_Request__1_·_yuuu_yuuu_portfolio.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60996/6c9ef55d-653c-4302-b5d1-4517c07e92f0.png">

<img width="1439" alt="Deploys___blissful-neumann-f43d8f.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60996/5467dacd-6777-09bb-5bd2-71703e21fa2a.png">

<img width="1439" alt="Deploy_details___blissful-neumann-f43d8f.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60996/55a85340-0482-e22f-5176-d8c6509f1388.png">

<img width="1439" alt="Banners_and_Alerts_と_yuuu_s_portfolio.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60996/9715059b-36df-520b-46bf-240ca64da8b0.png">

問題なければ、githubにてmasterへマージする。

## 感想

普段Ruby on Railsで開発していることもあって、Vue.jsでSPAを作るときに「このファイルってどこのディレクトリへ置くべきなんだろう？」「このモジュールのimportはどこで行うのが一般的なのか？」と迷うことが多々ありました。

Nuxt.jsだと、そのあたりがきちんと規約で決まっていて迷うことが少ないですね。
簡単にPWA対応できたこともGoodな点です。

そして、Netlifyは本当に便利だということを実感しました。