77
52

More than 5 years have passed since last update.

Nuxt.jsで静的サイトつくって最速でGithubPagesにあげる 〜ドラクエアプリ風ポートフォリオつくってたら平成が終わった〜

Last updated at Posted at 2019-05-29

TL;DR(要約)

  • Nuxt.js + GithubPages を使ってポートフォリオを作りました
  • ポートフォリオはこちら

自己紹介

個人的なプロジェクト「毎月サービスリリースで技術もノウハウもうっはうは祭り:fire:」をしています、ミツダマ(@mitudama)です。
1月の時間割メーカー、2月の俳句メーカー、3月の究極の選択メーカーに引き続き、今回はポートフォリオをつくりました。
ノウハウうっはうはになったのでシェアします!

作ったポートフォリオ

portfolio.gif

何で作ったか(ワイ記法)

ワイ「そろそろポートフォリオつくらななぁ」

ワイ「プログラマーのポートフォリオってどんなんがええんやろか?」

ワイ「デザイナーさんと違って見た目より動きとか機能重視の方がええんちゃうかな?」

ワイ「他の人のみたろ」

ワイ「@iwathiさんのポートフォリオ最高やんけ!!」

ワイ「先っちょだけ真似るンゴ」

ワイ「せや!どうせなら今風のドラクエアプリにしたらええんちゃうか!」

ワイ「作ったったったwww」

使った技術と参考サイト

  • GithubPages
    • 静的サイトのホスティングサービス
    • 無料 of 無料
    • yarn generate して生成されたdistディレクトリのアップ先

最速でポートフォリオを作るチュートリアル

環境構築

    vue init nuxt-community/starter-template front #front 部分は好きな名前で
    cd front
    npm install # Or yarn

    yarn dev

フォントの設定

(1) ドット風フォントをPixelMplus(ピクセル・エムプラス)からダウンロード

(2) assets配下にfontsフォルダを作成しフォントファイルを格納

(3) fontsフォルダに以下のcssファイルを作成

font.css

@font-face {
  font-family: 'PixelMplus10-Regular';
  src: url('~@/assets/fonts/PixelMplus10-Regular.ttf') format('truetype');
}

(4) nuxt.config.jsに以下の記述を追加

nuxt.config.js
module.exports = {
  /* 省略 */
  css: [
    '~/assets/fonts/font.css'
  ]
}

Vue CLI v3.0でローカルにあるフォントを適用する
How to embed font to all page with nuxt js

Vueのコーディング

以下コピペでOKです!

index.vue


<template>
  <section class="container">
    <div>
      <div class="prof_row">
        <div
        class="prof"
        v-bind:class="{ active: isProfile1Active }"
        @click="clickProfile1">
            <img class="prof_img" width="200px" height="200px" src="https://pbs.twimg.com/profile_images/1113461275147657216/iWNX45ac_400x400.jpg" />
        </div>
        <div
        class="prof"
        v-bind:class="{ active: isProfile2Active }"
        @click="clickProfile2">
            <img class="prof_img" width="200px" height="200px" src="https://pbs.twimg.com/profile_images/1131395626447429633/-wZugD8U_400x400.jpg" />
        </div>
      </div>
      <div class="prof_row">
        <div
        class="prof"
        v-bind:class="{ active: isProfile3Active }"
        @click="clickProfile3">
            <img class="prof_img" width="200px" height="200px" src="https://pbs.twimg.com/media/D7qrMoKU0AAjW-V.jpg" />
        </div>
        <div
        class="prof"
        v-bind:class="{ active: isProfile4Active }"
        @click="clickProfile4">
            <img class="prof_img" width="200px" height="200px" src="https://pbs.twimg.com/media/D7rCM0IUYAArCdK.jpg" />
        </div>
      </div>
    </div>
    <div class="footer-fixed">
      <div class="balloon_area">
        <button
        v-if="!talkFlg && (isProfile1Active || isProfile2Active || isProfile3Active || isProfile4Active)"
        @click="commandTalk">
          <span>はなす</span>
        </button>
        <div
          v-if="talkFlg"
          @click="talkNext"
          class="command_context">
          {{activeComment[talkIndex]}}
        </div>
      </div>
    </div>
  </section>
</template>

<script>

export default {
  data () {
    return {
      isProfile1Active: false,
      isProfile2Active: false,
      isProfile3Active: false,
      isProfile4Active: false,
      talkFlg: false,
      comment1:["こんにちわ枝豆エンジニアです","フリーランスのwebエンジニアやってます","アイコンに負けず劣らずぶっ飛んだツイートに定評があります"],
      comment2:["こんにちわ郡山です","高卒ニートからエンジニアになりました","趣味で「間違った指導法で新人を潰す愚かな上司」を根絶やしにする活動をしています"],
      comment3:["こんにちわ新世界の神ことがっちょです","Dungeon Template LibraryというOSSを開発しています","禁断の魔術で母なる大地を創造しましょう"],
      comment4:["こんにちわなおとです","外資系大企業を捨てWebエンジニアになりました","伸び代しかありません"],
      activeComment: null,
      talkIndex:0,
    }
  },
  methods: {
    clickProfile1(){
      this.resetActive();
      this.isProfile1Active = true;
      this.activeComment = this.comment1;
    },
    clickProfile2(){
      this.resetActive();
      this.isProfile2Active = true;
      this.activeComment = this.comment2;
    },
    clickProfile3(){
      this.resetActive();
      this.isProfile3Active = true;
      this.activeComment = this.comment3;
    },
    clickProfile4(){
      this.resetActive();
      this.isProfile4Active = true;
      this.activeComment = this.comment4;
    },
    resetActive(){
      this.isProfile1Active = false;
      this.isProfile2Active = false;
      this.isProfile3Active = false;
      this.isProfile4Active = false;
      this.talkIndex=0;
      this.talkFlg=false;
    },
    commandTalk(){
      this.talkFlg = true;
    },
    talkNext() {
      if(this.activeComment.length == this.talkIndex+1){
        this.talkIndex=0;
        this.talkFlg=false;
      }else{
        this.talkIndex++
      }
    },
  }
}
</script>

<style>
body{
  font-family: 'PixelMplus10-Regular';
}
.container {
  min-height: 100vh;
  display: flex;
  justify-content: center;
  align-items: center;
  text-align: center;
  margin-bottom: 200px !important;
}

.prof_row{
  display: flex;
  margin-top:30px
}
.prof{
  padding: 20px;
}
.prof_img {
  border: 6px double #000;
  border-radius: 20px;
}

.active {
  position: relative;
  display: inline-block;
}

.active:before {
  content: "";
  position: absolute;
  top: -25px;
  left: 50%;
  margin-left: -15px;
  border: 15px solid transparent;
  border-top: 15px solid #000;
  animation: Flash1 1s infinite;
}

.balloon_area{
  width:500px;
  height: 150px;
  background-color: rgba(0, 0, 0, 0.7)!important;
  border: 2px solid white;
  border-radius: 1em;
}

.footer-fixed {
  display: flex!important;
  position: fixed;
  justify-content: center;
  bottom: 5px;
  left: 6px;
  width: 100%;
  z-index: 3;
}

button{
  font-family: 'PixelMplus10-Regular';
  width:200px;
  font-size:24px;
  font-weight:bold;
  display:block;
  text-align:center;
  padding:8px 0 10px;
  margin-left: 10px;
  margin-top: 10px;
  color:#fff;
  border-radius:5px;
  background-color: #424242;
}

.command_context{
  color: white;
  font-size: 1.3em;
  line-height: 30px;
  padding: 20px 0 0 20px;
  height: 100%;
  margin-bottom: 0px;
  text-align: left;
}
/* アニメーション */
@keyframes Flash1{
  50%{
    opacity: 0;
  }
}

</style>

以下の画面になればOKです。

image.png

キャラの圧が強い。

Github Pages の環境設定

リポジトリの作成

公式サイトにしたがってusername.github.ioリポジトリを作成します

静的なWEBアプリケーションの生成

$ yarn generate

これでGitHub Pages のホスティングに必要なものが全て入った dist フォルダが作成されます

Push

$cd dist

dist $ git init

dist $ git add --all

dist $ git commit -m "Initial commit"

dist $ git remote add origin https://github.com/[username]/[username].github.io.git

dist $ git push -u origin master

※2回目以降はgit push -f origin master
(コードのバージョン管理用のリポジトリは別途用意してください)

Github pages確認

https://username.github.io
にアクセスしてみて表示されていれば成功です!!

感想

以上、ざっとやれば30分でポートフォリオが完成します!
あとは各画像を押した時のコメント内容に時間を使いましょう。
僕はこれで2週間潰れました。

興味のある方はぜひ作って見てください〜!

最後に

Twitterにて画像提供頂いた枝豆さん郡山さんがっちょさんなおとさん ありがとうございました!!

ではまた来月〜:wave:

(Twitterもフォローよろしくです)

77
52
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
77
52