【初心者】Vue.js初心者がポートフォリオサイトを作成＆公開する

#はじめに
Vue.jsを用いて，シングルページアプリケーション（＝SPA）のポートフォリオサイトを作成しました．

本記事では**Vue.js初心者が勉強からポートフォリオサイトを作成するまでの手順**を簡単に解説します．

[完成品はこちら](https://komekami.info/)
![キャプチャ.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1009493/5a89115a-5eec-7010-823b-9f9ced3e3649.jpeg)

>SPAとは，サイトのページ間の遷移に読み込みが発生しないアプリのこと．従って，普通のアプリ（または，サイト）よりサクサク動く（最初の読み込みは普通のサイトより少し時間がかかるらしい）．

#勉強＆環境構築
以下のVue公式チュートリアルとネコ本を一通りザっと読みました．

* [Vue公式チュートリアル](https://jp.vuejs.org/v2/guide/index.html)
* [基礎から学ぶVue.js （ネコ本）](https://www.amazon.co.jp/%E5%9F%BA%E7%A4%8E%E3%81%8B%E3%82%89%E5%AD%A6%E3%81%B6-Vue-js-MIO-ebook/dp/B07D9BYHMZ)

この中で重要そうな部分のみ実際にサンプルを作っていきました．5割程度の理解ではありましたが，**実際にサイトを作る過程で学んでいくのが最短**だと思ったため，気にせず先に進みました．

この勉強のなかで環境構築（Node.js, Vue-cliのインストール）も一緒に行いました．

#プロジェクトの基本設計
プロジェクトの基本設計は，1.ページ，2.デザイン，3.画像について行いました．

####1.ページ
ページに関しては，

* Topページ
* Profileページ（自己紹介ページ）
* Galleryページ（作品掲載ページ）
* Contactページ（連絡先掲載ページ）

の4ページを用意していくことにしました．
####2.デザイン
デザインに関しては，いちいち自分でcssを書くより，フレームワークを使おうと思い，Vuetifyを用いました．

[Vuetify](https://vuetifyjs.com/ja/)

このVuetifyのおかげでUIを用意することも，サイトデザインを考えることもなくなったので，サイト制作のハードルが下がりました．
####3.画像
画像に関しては，サイトの動作性を上げるためにCloudinaryを用いました．
[Cloudinary](https://cloudinary.com/)

画像のファイルサイズが大きすぎるので，画像の圧縮＆サイズ変更を行いました．
[iLoveIMG](https://www.iloveimg.com/ja)

#Topページ
![キャプチャ.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1009493/524d6f7f-7271-f28c-f64f-22bed72496c3.jpeg)

**Topページ内容**

* 複数の画像を6秒ごとにスライド表示するカルーセル
→Vuetifyのカルーセル機能を用いました.

コードは以下の通り．

```Vue:Top.vue
<template>
 <div class="top">
   <v-container
     class="fill-height"
     fluid
   >
     <v-carousel
       cycle
       height="70vh"
       show-arrows-on-hover
     >
       <v-carousel-item
         v-for="(item,i) in items"
         :key="i"
         :src="item.src"
         contain
       ></v-carousel-item>
     </v-carousel>
   </v-container>
 </div>
</template>

<script>
export default {
 data () {
   return {
     items: [
       {
         src: 'https://cloudinary上の画像リンク1.png'
       },
       {
         src: 'https://cloudinary上の画像リンク2.png'
       },
       {
         src: 'https://cloudinary上の画像リンク3.png'
       },
       {
         src: 'https://cloudinary上の画像リンク4.png'
       }
     ]
   }
 }
}
</script>
</script>

<style scoped>
 .top{
   padding-top: 20px;
 }
</style>
```

#Profileページ
![キャプチャ2.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1009493/0476e2e5-0859-d99f-4f26-0145e7824854.jpeg)

**Profileページ内容**

・プロフィール画像，名前，Twitterとpixivの外部リンクボタンをセットにしたカード
→Vuetifyのカード機能，ボタン機能を用いました．

・自身のツイート
→Twitterのライブラリをインストールし，表示させました．

コードは以下の通り．

```Vue:Profile.vue
<template>
 <div class="profile">
   <h1>Profile</h1>
     <v-container fluid>
     <v-row
       dense
       justify="center"
     >
       <v-col cols="12" sm="6" align="center">
         <v-card
           color="secondary"
           class="mx-auto"
           max-width="400"
           outlined
           shaped
         >
           <v-img
             class="text--primary align-end"
             gradient="to bottom, rgba(0,0,0,.1), rgba(0,0,0,.5)"
             height="300px"
             src="cloudinary上のプロフィール画像リンク.png"
           >
             <v-card-title>こめかみ (Komekami)</v-card-title>
           </v-img>
           <v-card-actions>
             <div class="btn">
               <!-- Twitterボタン -->
               <v-btn
                 elevation="5"
                 raised
                 outlined
                 target="_blank"
                 href="https://twitter.com/temple_circle"
               >
               Twitter
               </v-btn>
               <!-- Pixivボタン -->
               <v-btn
                 elevation="5"
                 raised
                 outlined
                 target="_blank"
                 href="https://www.pixiv.net/users/21060316"
               >
               Pixiv
               </v-btn>
             </div>
           </v-card-actions>
         </v-card>
       </v-col>
       <!-- Twitterタイムライン -->
       <v-col cols="12" sm="6" align="center">
         <div class="twitter-widget">
           <v-timeline
             :id="user_id"
             :source-type="'profile'"
             :options="{ 'height': twitterHeight, 'width': twitterWidth }" />
         </div>
       </v-col>
     </v-row>
   </v-container>
 </div>
</template>

<script>
import { Timeline } from 'vue-tweet-embed'
export default {
 components: {
   'v-timeline': Timeline
 },
 data () {
   return {
     user_id: 'temple_circle',
     twitterHeight: '60vh',
     twitterWidth: '400'
   }
 }
}
</script>

<style scoped>
 .v-btn{
   float: left;
   margin:10% 10px;
 }
</style>
```

#Galleryページ
![キャプチャ3.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1009493/5eb69768-65ea-2b11-e2d9-726e5cbdc4fd.jpeg)
![キャプチャ4.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1009493/dc9b57b3-751f-1915-6983-d7ae38cf9fd7.jpeg)

**Galleryページ内容**

・画像ギャラリー
→Vuetifyのグリッドシステムを用いました．

・画像をクリックすると拡大表示
→JavaScriptで記述．

コードは以下の通り．

```Vue:Gallery.vue
<template>
  <div class="gallery">
    <h1>Gallery</h1>
    <v-container
      class="fill-height"
      fluid
    >
    <v-dialog
      v-model="dialog"
      width="65vw"
      max-width="500px"
    >
      <template v-slot:activator="{ on, attrs }">
        <v-fade-transition mode="out-in">
          <v-row>
            <v-col
              v-for="item in items"
              :key="item"
              cols="6"
              sm="4"
              lg="3"
            >
              <v-img
                :src=item.src
                aspect-ratio="1"
                class="grey darken-4"
                v-bind="attrs"
                v-on="on"
                @click="modal(item.src)"
              ></v-img>
            </v-col>
          </v-row>
        </v-fade-transition>
      </template>
        <v-img
          :src=selectedImage
          contain
        >
        </v-img>
      </v-dialog>
    </v-container>
  </div>
</template>
<script>
export default {
  data () {
    return {
      dialog: false,
      selectedImage: null,
      items: [
        {
          name: 'イラスト',
          src: 'cloudinary上の画像リンク.png'
        },
　　　　 // 同様に記述していく
      ]
    }
  },
  methods: {
    modal (url) {
      this.selectedImage = url
    }
  }
}
</script>
```

#Contactページ

**Contactページ内容**

・メールアドレスを表示
→HTMLで記述．

コードは以下の通り．

```Vue:Contact.vue
<template>
  <div class="contact">
    <h1>Contact</h1>
    <br>
    <div class="contact-content wrapper">
      <p>ご連絡はkomekami0131☆gmail.com(☆→@)まで</p>
    </div>
  </div>
</template>

<style scoped>
  .contact-content{
    padding: 0 10px;
  }
</style>
```

#Netlifyで公開
Netlifyとは静的コンテンツのホスティングサービス．
簡単に公開できました．
[Netlify](https://www.netlify.com/)

また，お名前ドットコムで独自ドメインに課金しました，
[お名前ドットコム](https://www.onamae.com/)

#感想
勉強時間を含めて，40時間ほどでした．

サイトの今後の展望としては，
・Contactページにフォームを追加
・Garellyページにて，タグで一次創作と二次創作のフィルターを追加
・Garellyページにて，画像をクリックして拡大されてから次の画像にスワイプで遷移機能を追加
以上の3点を行っていきたいです．


#参考

* [Vue初心者のサイト制作](https://qiita.com/abouch/items/35d7a202f3e74c7d4c3e)
* [Vue初心者の学習方法](https://yusai.me/vue-js-portfolio/)
* [画像ビューワー](https://shimablogs.com/vue-modal)
* [画像ビューワー2](https://qiita.com/nnahito/items/e9f7f4be47352c18b1dd)
* [画像cdn化](https://qiita.com/kanaxx/items/7d88948c9f8f43cdf760)
* [Netlifyで公開](https://qiita.com/sugo/items/2ee64887d682b0dae635)
* [Netlifyで公開2](https://qiita.com/suin/items/743fe6252ad8af425c5e)
* [スタイル崩れ](https://qiita.com/goodtea0223/items/67360fa14954cd4a24ea)