【作って学ぶ】初心者でもできるVue.jsを使ったポートフォリオの作り方〜プロフィールページ作成編〜

はじめに

今回はVue.jsを使ってポートフォリオを作成する方法を紹介します。

開発環境の構築からコーディングなど数回に分けて紹介していきますので、ぜひご覧ください。

前回からの続きになります。

前回の記事はコチラ↓

関連記事

はじめに 今回はVue.jsを使ってポートフォリオを作成する方法を紹介します。 開発環境の構築からコーディングなど数回に分けて紹介していきますので、ぜひご覧ください。 前回からの続きになります。 前回の記事はコチラ↓ […]

さて、今回のテーマは「プロフィールページ作成編」です。参りましょう!!

プロフィールページについて

今回のテーマでは「プロフィールページ」を作成していきます。

前々回の記事で作成したページ設計図をもとに、デザインを含めてコードの解説を行いながら、コーディングを行っていきます。

ページ設計についての記事をご覧になりたい方はコチラ↓↓

関連記事

はじめに 今回はVue.jsを使ってポートフォリオを作成する方法を紹介します。 開発環境の構築からコーディングなど数回に分けて紹介していきますので、ぜひご覧ください。 前回からの続きになります。 前回の記事はコチラ↓ […]

コーディング

それでは早速コーディングをしていきましょう!!

こちらの記事で作成したVue.jsプロジェクトのワークスペースをVSCodeなどのテキストエディタで開いてください!

関連記事

はじめに 今回はVue.jsを使ってポートフォリオを作成する方法を紹介します。 開発環境の構築からコーディングなど数回に分けて紹介していきますので、ぜひご覧ください。 また、今回作成するポートフォリオの完成形はコチラになります[…]

続いて、プロフィールページのファイルである「Profile.vueを編集していきます。

vueファイルの構成について

Vue.jsで扱うvueファイルは大きく分けて、「template」、「script」、「style」の3つのエリアに分けられます。

今回はそれぞれのエリアに分けてコードの解説を行っていきます。

templateエリアのコーディング

templateエリアではHTMLを書いていきます。

Vue.jsではHTML<template></template>の間に書いていきます。

また、<template></template>の中には divタグ などのブロックを1つしか書くことができません。

上記のことから、ページを作っていくときは<template><div></div></template>の間にコードを書いていきます。

<template>
  <div id="profile_container">
    <img id="profile_img" src="../assets/avatar.png" alt="" />
    <h2>名前</h2>
    <div id="profile_description">
      <p class="profile_text">
        {{ Birthdate.year }}年{{ Birthdate.month }}月{{ Birthdate.day }}日産まれ
        {{ Age }}歳
      </p>
      <p class="profile_text">{{ Position }}</p>
      <div id="profile_intro" class="profile_text">
        <p>
          自己紹介文
        </p>
      </div>
    </div>
    <div id="socials">
      <a href="SNSリンク" class="social_icon">
        <img src="../assets/SNS1_logo.svg" />
      </a>
      <a href="SNSリンク" class="social_icon">
        <img src="../assets/SNS2_logo.png" />
      </a>
    </div>
  </div>
</template>

コードの解説をしていきます。

<img id="profile_img" src="../assets/avatar.png" alt="" />

3行目のコードはプロフィールのアイコンを表示するための imgタグ になります。

href に ../assets/avatar.png を指定しているため、Vueプロジェクトの中にある 「assetsフォルダ」の中に「avatar.png」という名前でアバター画像を保存しましょう。

<p class="profile_text">
  {{ Birthdate.year }}年{{ Birthdate.month }}月{{ Birthdate.day }}日産まれ
  {{ Age }}歳
</p>
<p class="profile_text">{{ Position }}</p>

6~9行目のコードは Vue.js の機能の一つである、Mustache(マスタッシュ) 構文 と言うものを使っています。

後ほど登場するscript」エリアで作成した変数を表示する際に使用します。

Mustache 構文は 「{{ 変数名 }}」のように「script」エリア内で作成した変数を中括弧」の2重で囲います。

<a href="SNSリンク" class="social_icon">
  <img src="../assets/SNS1_logo.svg" />
</a>
<a href="SNSリンク" class="social_icon">
  <img src="../assets/SNS2_logo.png" />
</a>

18~23行目に関してはSNSのリンクと、アイコンを作成しています。

imgタグ のsrcにて画像のファイルを指定しているため、アバターアイコンの時と同様にして Vueプロジェクト内のassetsフォルダ内に画像を保存してください。

scriptエリアのコーディング

scriptエリアではJavaScriptを書いていきます。

先ほど編集した Profile.vue</template> タグの下にコチラをコピペしてください。

<script>
export default {
  data() {
    return {
      Age: 0,
      Birthdate: {
        day: 29,
        month: 3,
        year: 2000,
      },
      Position: "",
    };
  },
  created() {
    this.InitAge();
    this.InitPosition();
  },
  methods: {
    InitAge() {
      let birthdate = new Date(
        this.Birthdate.year,
        this.Birthdate.month - 1,
        this.Birthdate.day
      );
      let today = new Date();
      let age = today.getFullYear() - birthdate.getFullYear();
      if (
        today.getMonth() < birthdate.getMonth() ||
        (today.getMonth() === birthdate.getMonth() &&
        today.getDate() < birthdate.getDate())
      ) {
        age--;
      }
      this.Age = age;
    },
    InitPosition() {
      let grade = this.Age - 21;
      if (grade < 1) {
        this.Position = "大学" + (4 - grade) + "年生";
      } else {
        this.Position = "社会人" + grade + "年目";
      }
    },
  },
};
</script>

コードの解説を行っていきます。

data() {
  return {
    Age: 0,
    Birthdate: {
      day: 12,
      month: 12,
      year: 2012,
    },
    Position: "",
  };
},

3~13行目では、このVueファイル内でグローバルで使用可能な変数の宣言を行っています。

先ほどの Mustache 構文 で使用している変数がコチラにあるものになります。

今回の場合は、年齢、誕生日オブジェクトの中に「日付」、「月」、「年」、「役職」を変数として宣言しています。

それぞれは「Age」、「Birthdate内day」、「Birthdate内month」、「Birthdate内year」、「Position」に対応しています。

methods: {
  InitAge() {
    let birthdate = new Date(
      this.Birthdate.year,
      this.Birthdate.month - 1,
      this.Birthdate.day
    );
    let today = new Date();
    let age = today.getFullYear() - birthdate.getFullYear();
    if (
      today.getMonth() < birthdate.getMonth() ||
      (today.getMonth() === birthdate.getMonth() &&
      today.getDate() < birthdate.getDate())
    ) {
      age--;
    }
    this.Age = age;
  },
  InitPosition() {
    let grade = this.Age - 21;
    if (grade < 1) {
      this.Position = "大学" + (4 - grade) + "年生";
    } else {
      this.Position = "社会人" + grade + "年目";
    }
  },
},

18~44行目については InitAge という関数と InitPosition という関数を定義しています。

InitAge関数ではページを開いた日付と、先ほどの変数に登録してある生年月日から年齢を計算する処理を行っています。

InitPosition関数ではInitAge関数によって計算した年齢から役職の「大学N年生」や「社会人N年目」などの計算と文字列の代入を行っています。

created() {
  this.InitAge();
  this.InitPosition();
},

14~17行目に関しては先ほど解説した関数をページを開いた際に実行する処理を書いています。

Vue.jsにはライフサイクルという、ページにアクセスしてから表示されるまでの一連の流れの中で特定のタイミングにおいて関数処理実行することができます。

createdの中に書かれた処理は画面がレンダリング(表示)された後に実行されます。

ここでは InitAge 関数InitPosition 関数を順番に実行しています。また、this というのは「この Vue ファイルで宣言されたもの」を意味しており、createdの中でmethodで宣言した関数を実行する際には必ず必要となります。

InitPosition関数ではInitAge関数によって計算したAgeを使用しているため、順番を逆にすると誤動作してしまいます。

勉強も兼ねて順番を逆にしてみるのもいいかもしれませんね。

style エリアのコーディング

続いてstyleエリアのコーディングを行っていきます。

今回はscssというcssの拡張版を使っています。

先ほど記述した</style>の下にコピペをして使用してください。

<style lang="scss" scoped>
  #profile_container {
    width: 100%;
    height: auto;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    #profile_img {
      width: 300px;
      height: 300px;
      border-radius: 100px;
      margin: 15px;
    }
    @media screen and (max-width: 400px) {
      #profile_img {
        width: 200px;
        height: 200px;
        border-radius: 75px;
      }
    }
    #profile_description {
      width: 100%;
      display: flex;
      flex-direction: column;
      align-items: center;
      justify-content: center;
      .profile_text {
        padding: 10px;
        font-size: 19px;
      }
      @media screen and (max-width: 400px) {
        .profile_text {
          padding: 10px 25px;
        }
      }
    }
    #socials {
      width: 100%;
      height: auto;
      margin-bottom: 20px;
      display: flex;
      flex-wrap: wrap;
      flex-direction: row;
      align-items: center;
      justify-content: center;
      .social_icon {
        width: 100px;
        height: 100px;
        border-radius: 100px;
        margin: 10px;
        img {
          width: 100%;
          height: 100%;
          border-radius: 100px;
          transition: 0.3s;
          &:hover {
            box-shadow: 0px 2px 10px -2px #777777;
          }
        }
      }
    }
  }
</style>

スタイルに関しては、処理的なものではないため、解説はないですが、FlexBoxというものを用いて表示の中央寄せや縦方向横方向の並びを指定しています。

また、styleタグの「scoped」はこのstyleタグに囲まれたスタイル命令が、このvueファイルのみで有効になる設定を指定しています。

Profile.vueファイル全体のコード

分割して書いたきたコードを1つのファイルとして表示すると次のようになります。

<template>
  <div id="profile_container">
    <img id="profile_img" src="../assets/avatar.png" alt="" />
    <h2>名前</h2>
    <div id="profile_description">
      <p class="profile_text">
        {{ Birthdate.year }}年{{ Birthdate.month }}月{{ Birthdate.day }}日産まれ
        {{ Age }}歳
      </p>
      <p class="profile_text">{{ Position }}</p>
      <div id="profile_intro" class="profile_text">
        <p>
          自己紹介文
        </p>
      </div>
    </div>
    <div id="socials">
      <a href="SNSリンク" class="social_icon">
        <img src="../assets/SNS1_logo.svg" />
      </a>
      <a href="SNSリンク" class="social_icon">
        <img src="../assets/SNS2_logo.png" />
      </a>
    </div>
  </div>
</template>
<script>
export default {
  data() {
    return {
      Age: 0,
      Birthdate: {
        day: 29,
        month: 3,
        year: 2000,
      },
      Position: "",
    };
  },
  created() {
    this.InitAge();
    this.InitPosition();
  },
  methods: {
    InitAge() {
      let birthdate = new Date(
        this.Birthdate.year,
        this.Birthdate.month - 1,
        this.Birthdate.day
      );
      let today = new Date();
      let age = today.getFullYear() - birthdate.getFullYear();
      if (
        today.getMonth() < birthdate.getMonth() ||
        (today.getMonth() === birthdate.getMonth() &&
        today.getDate() < birthdate.getDate())
      ) {
        age--;
      }
      this.Age = age;
    },
    InitPosition() {
      let grade = this.Age - 21;
      if (grade < 1) {
        this.Position = "大学" + (4 - grade) + "年生";
      } else {
        this.Position = "社会人" + grade + "年目";
      }
    },
  },
};
</script>
<style lang="scss" scoped>
  #profile_container {
    width: 100%;
    height: auto;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    #profile_img {
      width: 300px;
      height: 300px;
      border-radius: 100px;
      margin: 15px;
    }
    @media screen and (max-width: 400px) {
      #profile_img {
        width: 200px;
        height: 200px;
        border-radius: 75px;
      }
    }
    #profile_description {
      width: 100%;
      display: flex;
      flex-direction: column;
      align-items: center;
      justify-content: center;
      .profile_text {
        padding: 10px;
        font-size: 19px;
      }
      @media screen and (max-width: 400px) {
        .profile_text {
          padding: 10px 25px;
        }
      }
    }
    #socials {
      width: 100%;
      height: auto;
      margin-bottom: 20px;
      display: flex;
      flex-wrap: wrap;
      flex-direction: row;
      align-items: center;
      justify-content: center;
      .social_icon {
        width: 100px;
        height: 100px;
        border-radius: 100px;
        margin: 10px;
        img {
          width: 100%;
          height: 100%;
          border-radius: 100px;
          transition: 0.3s;
          &:hover {
            box-shadow: 0px 2px 10px -2px #777777;
          }
        }
      }
    }
  }
</style>

各ページの動作確認

ここまでで作成したページファイルやRouterの設定の動作確認を行います。

コンソールを開いて次のコマンドを入力してください。

npm run serve

コマンドを実行して次のようなURLが発行されたら、こちらのURLにブラウザからアクセスしてください。

http://localhost:8080

また、コンソールではなく、Vue UI を使ってGUIベースでテストを行うこともできます。

その方法はこちらの記事をご覧ください。

関連記事

はじめに 今回はVue.jsを使ってポートフォリオを作成する方法を紹介します。 開発環境の構築からコーディングなど数回に分けて紹介していきますので、ぜひご覧ください。 また、今回作成するポートフォリオの完成形はコチラになります[…]

発行されるURLにアクセスしてみてください。

今回はプロフィールページを編集したので、アクセス先は「http://localhost:8080になります。

Router設定など、どのURLにアクセスしたらどのページが表示されるかは、コチラをご覧ください。

関連記事

はじめに 今回はVue.jsを使ってポートフォリオを作成する方法を紹介します。 開発環境の構築からコーディングなど数回に分けて紹介していきますので、ぜひご覧ください。 前回からの続きになります。 前回の記事はコチラ↓ […]

また、「http://localhost:8080」にアクセスした際に表示される見た目が、大体でコチラのようになっていれば、今回は成功です!

終わりに

今回は『Vue.jsを使ったポートフォリオの作り方』のpart4としてプロフィールページの作成についてお伝えしてきました!

次回もページの見た目などをコーディングしていきます!

お疲れ様でした!!

最新情報をチェックしよう!