Nuxt.js + Vuetifyで手っ取り早くポートフォリオサイトを作る
プロジェクト作成
create-nuxt-appでやると楽。
最近はnpmの性能が上がっているらしいので脱yarnする。
デザインは見た目や保守性が良くなればUIフレームワークを使った方が良い派なのでVuetifyを使う。
チーム開発でもないのにスペースなどに一々文句を言われたり勝手に修正されるのも癪なのでeslintとprettierは入れない。
$ yarn create nuxt-app portfolio ? Project name portfolio ? Project description tetsugi's portfolio ? Use a custom server framework none ? Use a custom UI framework vuetify ? Choose rendering mode Single Page App ? Use axios module no ? Use eslint no ? Use prettier no ? Author name tetsugi ? Choose a package manager npm
PWA化
PWA用のモジュールをインストールする。
導入手順はドキュメントに書いてある。
$ npm i -S @nuxtjs/pwa
nuxt.config.js
に追記。
module.exports = { /* 省略 */ modules: [ '@nuxtjs/pwa' ], manifest: { name: "tetsugi's portfolio", lang: 'ja' }, /* 省略 */ }
.gitignore
にsw.*
を追記。
また、アイコンとする画像をstatic/icon.png
に配置する。512 * 512
以上を推奨。
デザインする
とりあえず次の項目を入れることにした。
- ジャンボトロン・メニュー
- 自己紹介
- スキル
- 作ったもの一覧
- コンタクト
後で自分が変更しやすいよう、各パーツはコンポーネントとして分離することにする。
以下、少し考えた部分だけまとめる。
ジャンボトロン
Vuetifyのv-jumbotron
は非推奨になったようなので、代わりにv-img
とv-responsive
を組み合わせて使う。
v-img
のgradient
属性で軽くグラデーションをつけるとそれっぽく見える気がする。
文字やボタンが中央揃えになるようにalign-center
やtext-xs-center
をつける。
Google Fontsから気に入ったフォントを選んで、タイトルに設定すると見栄えがよくなるかも。
ボタンには該当IDの要素までスクロールする処理を持たせた。
<template> <v-img src="/img/jumbotron.jpg" max-height="320px" gradient="to top right, rgba(63,81,181, .4), rgba(25,32,72, .4)"> <v-container fill-height> <v-layout align-center> <v-flex text-xs-center> <h3 class="display-3 white--text"> <span class="jumbotron-title">Tetsugi's Portfolio</span> </h3> <div class="mt-4"> <v-btn @click="$vuetify.goTo('#profile', options)">PROFILE</v-btn> <v-btn @click="$vuetify.goTo('#skills', options)">SKILLS</v-btn> <v-btn @click="$vuetify.goTo('#works', options)">WORKS</v-btn> <v-btn @click="$vuetify.goTo('#contact', options)">CONTACT</v-btn> </div> </v-flex> </v-layout> </v-container> </v-img> </template> <script> export default { data() { return { options: { duration: 700, offset: 0, easing: 'easeOutCubic' } } } } </script> <style scoped> .jumbotron-title { font-family: 'Orbitron', sans-serif !important; border-bottom: solid 1px white; } </style>
スキルについて書くカード
以下のようにすると各スキルの説明や評価を修正しやすいと思った。
<skill title="言語などの名前" color="blue" :rating="3"> <template slot="text"> 説明 </template> <template slot="list"> <skill-list-item name="その言語などに関わりが深いフレームワークなどの名前" :rating="2"> 説明 </skill-list-item> </template> </skill>
たとえばJavaScriptなら、slot="text"
のところにJavaScriptの使用歴や感想を書き、skill-list-item
にVue.jsやReactがどの程度いじれるか書いていく。
コンポーネントとして切り出しているので、デザインが気に食わなくなったらSkill.vue
やSkillListItem.vue
を変更すればすぐに見た目を変えられる。
あまり変な共通化をすると罠になるが、今回は小さいプロダクトなので便利になればそれでいい。
フローティングボタン
各項目にスクロールするメニューが上部についているため、一番上にスクロールできるフローティングボタンをつけたくなった。
ジャンボトロンのmax-height
を320px
にしたので、300px
ほどスクロールしたら一番上に戻るボタンを右下に常に表示することにする。
右下固定はfixed bottom right
属性を付与すれば実現できる。
スクロールに追従して一番上からのオフセットを状態として保持し、computed
で300px
を超えているかどうかを返せば、v-show
で表示非表示を切換できそうだ。
スクロールのアニメーションはジャンボトロンと同じものを使いたかったので、ジャンボトロンがあるindex.vue
の適当な箇所に次のコードを追記した。
スクロールを検知して処理を呼び出すため、適当な要素の属性にv-scroll="onScroll"
を追加した。
<template> <v-fab-transition> <v-btn fixed dark fab bottom right color="pink" v-show="showFloating" @click="$vuetify.goTo(0, options)"> <v-icon>keyboard_arrow_up</v-icon> </v-btn> </v-fab-transition> </template> <script> export default { data() { return { offsetTop: 0, } }, computed: { showFloating() { return this.offsetTop >= 300 } }, methods: { onScroll(e) { this.offsetTop = document.documentElement.scrollTop || document.body.scrollTop } } } </script>
デプロイ
GitHub Pagesのユーザーページとしてポートフォリオサイトを公開したい。
ついでに自動でデプロイビルドするようにして欲しい。
Nuxt公式にGitHub Pagesにデプロイする手順が載っているが、これではリポジトリ用のページになってしまう。
少し考えた結果、develop
ブランチに成果物をコミットし、master
にデプロイすることにした。
残念ながら、ユーザーページのリポジトリではTravis CIで自動ビルドデプロイすることはできないようだ。
push-dir
というツールをインストールする。
dist
やbuild
ディレクトリを別のブランチにプッシュできるイカしたツールだ。
GitHub Pagesではmaster
やgh-pages
ブランチにプッシュする必要があるため、力を発揮する。
$ npm i -D push-dir
package.json
のnpm scriptsの部分を追記する。
--dir
には対象とするディレクトリ、--branch
にはプッシュ先のブランチ名を書く。
{ "scripts": { "dev": "nuxt", "build": "nuxt build", "start": "nuxt start", "generate": "nuxt generate", "deploy": "push-dir --dir=dist --branch=master --cleanup", "gd": "npm run generate && npm run deploy" } }
push-dir
はHTTPSでは疎通できずエラーを吐くのでSSHにしておく。これで少し詰んだ。
毎回パスワード入力が求められるのもアレなので、最初からSSHにしておくべき。
あとは更新したくなったらnpm run gd
すればいい。楽。
感想
create-nuxt-app
とGitHub Pagesなどを使えば高速でWebページを作って無料でホスティングできる。
PWA化したので、AndroidのChromeやiOSのSafariでホーム画面に追加することで、見せたい人にすぐに見せびらかせる。
慣れれば見栄えが良くて保守性も高いものをかなり速く作れそう。