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

はじめに

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

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

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

前回の記事はコチラ↓

関連記事

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

さて、今回のテーマは「ギャラリーページ作成編」です。参りましょう!!

ギャラリーページについて

今回のテーマでは「ギャラリーページ」を作成していきます。

ギャラリーページでは今まで制作したものなどを紹介するページになります。

今後も制作物が増えた際に簡単に追加できるような構造にしたいと思いますので、それを実現していきます。

ページ設計図をもとに、デザインを含めてコードの解説を行いながら、コーディングを行っていきます。

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

関連記事

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

コーディング

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

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

関連記事

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

続いて、プロフィールページのファイルである「Gallery.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="gallery_container">
    <input
      id="gallery_searchbar"
      type="text"
      placeholder="ギャラリーを検索"
      @input="UpdateCards"
      v-model="search_text"
    />
    <div id="galleries">
      <div class="card" v-for="card in disp_cards" :key="card.id">
        <img class="card_img" :src="card.image" />
        <div class="card_title">
          {{ card.title }}
        </div>
        <div class="card_description">
          {{ card.description }}
        </div>
      </div>
    </div>
  </div>
</template>

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

<input
  id="gallery_searchbar"
  type="text"
  placeholder="ギャラリーを検索"
  @input="UpdateCards"
  v-model="search_text"
/>

3~9行目のコードは複数存在する制作物をの検索するため検索ボックスである inputタグ になります。

typeには“text”を指定しています。1行の文字を入力することができます。placeholerにはこの検索ボックスの説明入力します

@input=”UpdateCards”Vue.js 特有のイベントハンドラというもので、文字の入力がされるたびに次に説明するscriptタグで定義した関数である UpdateCards という関数が実行されます。

v-model=”search_text” では次で説明する scriptタグの中で宣言した変数に値が代入される設定を行なっています。つまり、テキストボックスに文字を入力されると search_text という変数に値が入力される仕組みになっています。

<div class="card" v-for="card in disp_cards" :key="card.id">

11行目のコードは javascript のエリアで作られた変数を一定のルールに則ってループ表示するものになります。

今回は後ほど定義する disp_cards という変数の中身をループ表示する処理を行なっています。

scriptエリアのコーディング

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

<script>
export default {
  data() {
    return {
      search_text: "",
      disp_cards: [],
      cards: [
        {
          title: "成果1",
          description: "成果1の説明",
          image: require("../gallery/○○○.png"),
        },
      ],
    };
  },
  created() {
    this.UpdateCards();
  },
  methods: {
    UpdateCards() {
      this.disp_cards = [];
      if (this.search_text != "") {
        for (let Target_Key in this.cards) {
          if (
            this.cards[Target_Key].title.indexOf(this.search_text) > -1 ||
            this.cards[Target_Key].description.indexOf(this.search_text) > -1
          ) {
            this.disp_cards.push(this.cards[Target_Key]);
          }
        }
      } else {
        this.disp_cards = this.cards;
      }
    },
  },
};
</script>

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

data() {
  return {
    search_text: "",
    disp_cards: [],
    cards: [
      {
        title: "成果1",
        description: "成果1の説明",
        image: require("../gallery/○○○.png"),
      },
    ],
  };
},

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

search_text は検索ボックスに入力された値を格納する変数になります。

disp_cards はページに表示する成果を格納する変数になります。

最後に cards は成果のデータ全てを格納しておく変数になります。

image: require("../gallery/○○○.png"),

なお、require(” “) の 「” “」の中にはギャラリー一覧で使用する画像のパスを指定しておいてくださいね!

created() {
  this.UpdateCards();
},

16~18行目については Vue.js のライフサイクルの中の created というタイミングで処理が実行されるものになります。

今回の場合は created はサイトが表示された後に実行されるという考えで問題ありません。

上記のことからサイトが表示されたタイミングで UpdateCards という関数を実行します。

methods: {
  UpdateCards() {
    this.disp_cards = [];
    if (this.search_text != "") {
      for (let Target_Key in this.cards) {
        if (
          this.cards[Target_Key].title.indexOf(this.search_text) > -1 ||
          this.cards[Target_Key].description.indexOf(this.search_text) > -1
        ) {
          this.disp_cards.push(this.cards[Target_Key]);
        }
      }
    } else {
      this.disp_cards = this.cards;
    }
  },
 },

19~35行目に関しては先ほど解説した UpdateCards という関数を定義しています。

UpdateCards 関数では初めに表示用の disp_cards 変数を初期化します。

続いて検索ボックスの値が格納される search_text 変数に値が入っているかどうかを確認します。

もし値が入っていればギャラリーの全データが格納されている変数 cards の中から検索をします。

値が入っていない場合は全データが格納されている変数 cards の値をそのまま表示用変数 disp_cards に代入します。

style エリアのコーディング

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

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

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

<style lang="scss" scoped>
#gallery_container {
  width: 100%;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  #gallery_searchbar {
    width: 600px;
    height: 40px;
    padding: 0 30px;
    margin: 20px 0;
    border: 1px solid #aaa;
    border-radius: 999px;
    outline: none;
  }
  @media screen and (max-width: 400px) {
    #gallery_searchbar {
      width: 300px;
      height: 40px;
      padding: 0 10px;
      margin: 10px 0;
    }
  }
  #galleries {
    width: 80%;
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    align-items: center;
    .card {
      width: 250px;
      height: 300px;
      border-radius: 10px;
      box-shadow: 0px 2px 8px -4px #777777;
      margin: 10px;
      display: flex;
      flex-direction: column;
      justify-content: center;
      align-items: center;
      position: relative;
      .card_img {
        width: 100%;
        height: 250px;
        border-radius: 10px 10px 0 0;
      }
      .card_description {
        background-color: #fff;
        width: 100%;
        height: 250px;
        padding: 10px;
        margin-bottom: 50px;
        font-size: 15px;
        font-weight: 900;
        position: absolute;
        opacity: 0;
        transition: 0.3s;
        &:hover {
          opacity: 1;
          background-color: rgba($color: #fff, $alpha: 0.9);
        }
      }
      .card_title {
        width: 100%;
        height: 50px;
        font-size: 17px;
        font-weight: 900;
        display: flex;
        flex-direction: column;
        justify-content: center;
        align-items: center;
      }
    }
  }
}
</style>

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

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

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

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

<template>
  <div id="gallery_container">
    <input
      id="gallery_searchbar"
      type="text"
      placeholder="ギャラリーを検索"
      @input="UpdateCards"
      v-model="search_text"
    />
    <div id="galleries">
      <div class="card" v-for="card in disp_cards" :key="card.id">
        <img class="card_img" :src="card.image" />
        <div class="card_title">
          {{ card.title }}
        </div>
        <div class="card_description">
          {{ card.description }}
        </div>
      </div>
    </div>
  </div>
</template>
<script>
export default {
  data() {
    return {
      search_text: "",
      disp_cards: [],
      cards: [
        {
          title: "成果1",
          description: "成果1の説明",
          image: require("../gallery/○○○.png"),
        },
      ],
    };
  },
  created() {
    this.UpdateCards();
  },
  methods: {
    UpdateCards() {
      this.disp_cards = [];
      if (this.search_text != "") {
        for (let Target_Key in this.cards) {
          if (
            this.cards[Target_Key].title.indexOf(this.search_text) > -1 ||
            this.cards[Target_Key].description.indexOf(this.search_text) > -1
          ) {
            this.disp_cards.push(this.cards[Target_Key]);
          }
        }
      } else {
        this.disp_cards = this.cards;
      }
    },
  },
};
</script>
<style lang="scss" scoped>
#gallery_container {
  width: 100%;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  #gallery_searchbar {
    width: 600px;
    height: 40px;
    padding: 0 30px;
    margin: 20px 0;
    border: 1px solid #aaa;
    border-radius: 999px;
    outline: none;
  }
  @media screen and (max-width: 400px) {
    #gallery_searchbar {
      width: 300px;
      height: 40px;
      padding: 0 10px;
      margin: 10px 0;
    }
  }
  #galleries {
    width: 80%;
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    align-items: center;
    .card {
      width: 250px;
      height: 300px;
      border-radius: 10px;
      box-shadow: 0px 2px 8px -4px #777777;
      margin: 10px;
      display: flex;
      flex-direction: column;
      justify-content: center;
      align-items: center;
      position: relative;
      .card_img {
        width: 100%;
        height: 250px;
        border-radius: 10px 10px 0 0;
      }
      .card_description {
        background-color: #fff;
        width: 100%;
        height: 250px;
        padding: 10px;
        margin-bottom: 50px;
        font-size: 15px;
        font-weight: 900;
        position: absolute;
        opacity: 0;
        transition: 0.3s;
        &:hover {
          opacity: 1;
          background-color: rgba($color: #fff, $alpha: 0.9);
        }
      }
      .card_title {
        width: 100%;
        height: 50px;
        font-size: 17px;
        font-weight: 900;
        display: flex;
        flex-direction: column;
        justify-content: center;
        align-items: center;
      }
    }
  }
}
</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としてプロフィールページの作成についてお伝えしてきました!

今回までの実装でポートフォリオがある程度完成したのではないでしょうか?

本ブログではこれからも情報発信をしていきますので、フォローお願いします!!

お疲れ様でした!!

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