※ 本投稿はTechCommit Advent Calendar 2019 11日目の記事です。
はじめに
普段はWeb製作会社でコーダーのアルバイトをしている大学4回生です。内定先の会社でVue.jsを使っているということもあり、Vue.jsで簡単に何か作成してみようと思いポートフォリオを作成しました。
今回はVue.js + Vuetify + Vue Router を用いてSPAのポートフォリオを作成し、Firebaseにホスティングしたのでその流れ等について書いています!
実際に作成したポートフォリオ
https://vue-portfolio-25939.firebaseapp.com
環境
- Vue CLI v4.1.1
- Node.js v12.6.0
- npm v6.9.0
ポートフォリオを作成する前に考えたこと
何を掲載するか
- トップページ
- 簡単な自己紹介
- 作品
- スキル
- お問い合わせ
ざっとこんな感じで構成することにしました。
Vue.jsでどのようなものが作れるかを確認
「Vue.js ポートフォリオ」で検索すると多くの記事が出てくるので、それを一通り読みました。
参考になった記事
- フロント未学習の大学生が1週間でVue.jsを使ったポートフォリオを作った話
- Vueを学び、SPA対応のポートフォリオサイトを自作するまでの道のり
- 【Vue.js入門】独学1週間でSPA対応の簡易ポートフォリオサイトを自作してみた!
- Vue.jsでドラクエ風のポートフォリオを作った話
- Vue.js + Firebaseでポートフォリオを作ろう!
- Vue.js + Firebase functionsでお問い合わせフォームを作成する
デザインを考える
Cacooというサービスを使って簡単にワイヤーフレームを作ってみました。
シート6枚までは無料で使えるので今回作成するポートフォリオのようにページ数の少ないコンテンツであれば無料枠でも充分です。
実装していくと「やっぱりここをこういう風にしたい」と思ったりもして、多少変更しました。
##実際にポートフォリオを作成していく
仕様
- デザインはVuetifyを使用
- SPA構築(Vue Router)
- テキストアニメーション
- モーダルウィンドウ
- お問い合わせフォーム(Firebase Functionsを用いてメールフォーム作成)
- アイコンはfont-awesomeを使用
Vuetify + Vue Router
vue add vuetify
でvuetifyを追加、モードはDefaultを選択。
Vue Routerに関しては、vue create
時にRouterを選択し、vue-routerを使えるようにしました。
import Vue from 'vue'
import VueRouter from 'vue-router'
import Top from '@/components/Top'
import Profile from '@/components/Profile'
import Work from '@/components/Work'
import Skill from '@/components/Skill'
import ContactForm from '@/components/ContactForm'
Vue.use(VueRouter)
const routes = [
{
path: '/',
component: Top
},
{
path: '/profile',
component: Profile
},
{
path: '/works',
component: Work
},
{
path: '/skills',
component: Skill
},
{
path: '/contact',
component: ContactForm
},
]
const router = new VueRouter({
mode: 'history',
base: process.env.BASE_URL,
routes
})
export default router
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import vuetify from './plugins/vuetify';
import '@fortawesome/fontawesome-free/css/all.css'
Vue.config.productionTip = false
new Vue({
router,
vuetify,
render: h => h(App)
}).$mount('#app')
単一ファイルコンポーネントを用いての実装だったので、App.vue
には以下のように記述。
<template>
<v-app>
<v-content>
<header-menu></header-menu>
<router-view/>
</v-content>
</v-app>
</template>
<script>
import HeaderMenu from './components/HeaderMenu';
export default {
name: 'App',
components: {
HeaderMenu,
},
data: () => ({
//
}),
};
</script>
ちなみにヘッダーメニュー部分は以下のような感じです。hidden-sm-and-down
、hidden-md-and-up
をクラスに付与することにより、smサイズの時にテキストを隠し、アイコンを表示。mdサイズの時にアイコンを隠し、テキストを表示させています。
<template>
<v-toolbar
color="teal"
dark
class="d-flex justify-center"
>
<v-toolbar-items v-for="(item, index) in items" :key="index">
<v-btn text class="hidden-sm-and-down">
<router-link v-bind:to="item.path">
{{ item.title }}
</router-link>
</v-btn>
<v-btn text class="hidden-md-and-up">
<router-link v-bind:to="item.path">
<v-icon medium>{{ item.icon }}</v-icon>
</router-link>
</v-btn>
</v-toolbar-items>
</v-toolbar>
</template>
<script>
export default {
name: 'app',
data () {
return {
items: [
{
title: 'トップ',
icon: 'fas fa-home',
path: '/'
},
{
title: 'プロフィール',
icon: 'far fa-id-badge',
path: '/profile'
},
{
title: '作品',
icon: 'fas fa-folder',
path: '/works'
},
{
title: 'スキル',
icon: 'fas fa-code',
path: '/skills'
},
{
title: 'お問い合わせ',
icon: 'far fa-envelope',
path: '/contact'
}
]
}
}
}
</script>
お問い合わせフォーム
送信サーバとしてgmailを使うため、環境変数に以下を追加
$ firebase functions:config:set gmail.email="gmailID" gmail.password="gmailPassword" admin.email="adminAddress"
バリデーションはv-text-fieldのrulesオプションを使って実装しました。
(略)
<v-text-field
v-model="contactForm.name"
:rules="contactFormValidation.nameRules"
label="名前"
required
></v-text-field>
(略)
<script>
import { functions } from '@/plugins/firebase'
export default {
data: () => ({
contactForm: {
name: '',
},
contactFormValidation: {
valid: false,
nameRules: [v => !!v || '名前は必須項目です'],
},
})
}
</script>
(略)
ビルドとデプロイ
npm run build
でビルドし、firebase deploy
でデプロイ完了です!
まとめ
今回は初めて、vue.jsを用いてポートフォリオを作成しました。今後はサーバーサイドと連携させたものを作りたいと思っています!
間違っているところなどありましたら、コメントで教えていただけると幸いです。