6
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Vue.js勉強したのでエンジニアポートフォリオサイト作ってみた

Last updated at Posted at 2021-05-04

はじめに

Vue.jsの勉強がてらポートフォリオサイト作って公開しました。せっかく作ったので忘れないように技術的な内容をまとめようと思います。

Vue.jsやアニメーションなど効果的には使えていないと思うので、温かい目で見てもらえると幸いです。

Web開発の経験について

5,6年前にとある企業の社内報サイトと人材管理Webシステムの開発に携わり、下記のWeb系の技術経験が1~2年ほどあります。(5年以上経つのでかなり忘れていました。。。)

HTML, CSS, AngularJS, SpringBoot, MySQLなど

モチベーション

  • たまたまWebデザインの最新トレンド記事を読んで、自分のデザイン感覚がアップデートできていないことに気づいた。最低限の感覚はアップデートしたい
  • せっかくなのでフロントエンドの人気のフレームワークに触れてみたい
  • フロントエンドの忘れた知識を取り戻したい
  • 今まで技術的な発信してこなかったので何か発信したい

作成したポートフォリオサイトについて

作成したサイトはこちら。Ike's Portfolio

技術要素

  • Vue.js
  • 単一ファイルコンポーネント
  • Vue Router / SPA
  • Element UI
  • デザイン
  • パララックス
  • アニメーション
  • マウスカーソルの動きに合わせて動く背景(パララックスの一部かも?)
  • その他
  • Firebase Hosting

画面構成

TOP

  • アニメーション
  • マウスカーソルの動きに合わせて動く背景
    スクリーンショット

Profile

スクリーンショット 2021-04-30 18.52.58.png

Skill Set

  • アニメーション(スライドイン)
  • パララックス
    Ike-s-Portfolio_skill

Works

  • アニメーション(フェイドイン)
  • element ui (プログレスバー)
    Ike-s-Portfolio_work

Contact

Ike-s-Portfolio_contact

実装

全体

各セクションを単一ファイルコンポーネントで作成し、大枠のvueから呼び出すような構成にしました。

App.vue
<template>
  <div id="app">
    <Header />
    <!-- ルーティング時の表示領域を準備 -->
    <router-view/> <!-- Home.vueが呼ばれる -->
    <Footer />
  </div>
</template>
Home.vue
<template>
  <div class="home">
    <Splash />
    <Profile />
    <Skill />
    <Works />
    <Contact />
  </div>
</template>

アニメーション(フェードイン、スライドイン)

アニメーションは複数ファイルで利用できるようコンポーネント化しました。「slot」を利用してアニメーションさせたい要素を別ファイルから差し込めるようにしています。
参考記事:[Vue.js]スクロールでコンテンツがフェードインする実装

また、アニメーション処理については、まずスクロール位置を管理するため「addEventListener()」を用いてスクロールイベントをリスナー登録します。特定の位置までスクロールしたら変数visibletrueにし、アニメーションを指定するcssのclassが付与されるようにしています。

下記はフェードインのソースコードですが、スライドインも同様に作成しています。

FadeInComponent.vue
<template>
  <div ref="fade" :class="{fadein: visible, hidden: !visible}">
    <slot v-show="visible"></slot>
  </div>
</template>

<script>
export default {
  name: 'FadeInComponent',
  data () {
    return {
      visible: false
    }
  },
  created () {
    window.addEventListener('scroll', this.handleScroll)
  },
  destroyed () {
    window.removeEventListener('scroll', this.handleScroll)
  },
  methods: {
    handleScroll () {
      if (!this.visible) {
        var top = this.$refs.fade.getBoundingClientRect().top
        this.visible = (top + 100) < window.innerHeight
      }
    }
  }
}
</script>

<style scoped>
.hidden {
  opacity: 0;
}

.fadein {
  animation: fadeIn 1s;
  opacity: 1;
}

@keyframes fadeIn {
  0% {
    opacity: 0;
    transform: translateY(50px);
  }
  100% {
    opacity: 1;
    transform: translateX(0px);
  }
}
</style>

アニメーションさせたい要素を上記コンポーネントで挟み込むことで動作するようにしています。

Skill.vue
    <FadeIncomponent>
      <h1 class="title">Skill Set</h1>
    </FadeIncomponent>

パララックス

わかりにくいですが、Skill Setの背景にパララックスを適用しています。
Ike-s-Portfolio_skill

パララックスはdirectivesを使い、HTMLタグに指定できるようにしました。
scroll量に合わせて背景画像のポジションをbackground-position-yで変化させることで実現しています。

参考記事:https://note.com/rottenmarron/n/nb7a23b1483ca

Skill.vue(directives箇所を抜粋)
<script>
~~~~~~~~~~~~ 省略 ~~~~~~~~~~~~~~
  directives: {
    parallax: {
      inserted (el, binding) {
        el.setAttribute( // 初期状態のスタイル
          'style',
            `
              background-position: center top;
              background-size: initial;
              backgroung-repeat: no-repeat;
              background-position-y: ${window.scrollY / binding.value.denominator}px;
            `
        )
        window.addEventListener('scroll', () => {
          el.setAttribute( // スクロール量に応じて動的に変化するスタイル
            'style',
            `
              background-position: center center;
              background-size: initial;
              backgroung-repeat: no-repeat;
              background-position-y: ${window.scrollY / binding.value.denominator + 300}px;
            `
          )
        })
      }
    }
  },
~~~~~~~~~~~~ 省略 ~~~~~~~~~~~~~~
</script>

下記のようにHTMLタグにdirectivesを指定することで要素にパララックス効果を適用しています。

Skill.vue(directiveの指定)
  <div id="skill" class="bg-blar" :class="{safari: safari}" v-parallax="{
        height: '100vh',
        denominator: 1.8
    }">

マウスカーソルの動きに合わせて動く背景

parallax.jsライブラリを使用しました。

視差効果を付与したい要素に対してnew Parallaxでオプションを指定するだけでマウスカーソルの位置に合わせて要素が移動します。

Splash.vue(HTML)
    <div id="parallax">
      <div data-depth="0.2">
        <h1 class="title">
          Ike's Portfolio
        </h1>
        <span>Full Stack Engineer</span>
      </div>
    </div>
Splash.vue(script)
<script>
export default {
~~~~~~~~~~~~ 省略 ~~~~~~~~~~~~~~
  mounted () {
    this.$nextTick(function () {
      var layer = document.getElementById('parallax')
      const parallax = new Parallax(layer, {
        scalarX: 10.0, // X軸の移動速度と範囲を増減
        scalarY: 10.0, // Y軸の移動速度と範囲を増減
        frictionX: 0.1, // X軸のレイヤーの速度。0.00〜1.00の範囲内で指定可能
        frictionY: 0.1, // Y軸のレイヤーの速度。0.00〜1.00の範囲内で指定可能
      })
    })
    window.addEventListener('scroll', this.onScroll)
  },
~~~~~~~~~~~~ 省略 ~~~~~~~~~~~~~~
</script>

プログレスバー

Element UIライブラリを利用しました。
Elementライブラリ導入後に、<el-progress>タグを利用することで簡単にプログレスバーを描画することができます。

プログレスバー

Skill.vue
<div class="progress-wrapper">
  <span>Swift / Objective-C</span>
  <el-progress :percentage="80"></el-progress>
</div>

Web公開

Firebase Hosting

ホスティングにはFirebase Hostingを利用しました。以下の理由で選定しました。

  • 将来的に他のFirebaseサービス(Cloud Functions for Firebaseなど)と組み合わせる可能性あり
  • サーバ費用、ドメイン費用が無料
  • CDNエッジサーバのSSDキャッシュに保存されるので、コンテンツを高速に配信できる

導入方法はFirebase Hosting公式サイト記載の導入手順を実行すればお手軽に導入できます。

今後の展望

  • 内容が薄いので厚くしたい。特に個人開発の欄を増やしたい
  • 検索しても出て来ないのでSEO対策する
  • CSSを整理したい
  • ブログ作って発信する量を増やしたい
  • 色々効果的に利用できていないので、UI/UXデザインを学びたい
  • 移り変わりが早いので定期的に新しいトレンドを学ぶ

最後まで閲覧いただきありがとうございました。もしコメントがあればいただけますと嬉しいです。

6
8
0

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
6
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?