Vue.jsを用いたWebページ制作 ~その5~

Vue.js シリーズの第5弾です。

今回はトップページの中ほどにある「お知らせ」や「会社情報」などへリンクするエリアを再現する中で、前回に引き続きコンポーネントを使うメリットを実感してみましょう。

今回作るもの

今回はコンポーネントを使って作ってみます。

コンポーネントとは画面を構成する部品を独立したピースに分割し、再利用できるようにする仕組みです。コンポーネントが使えるのも Vue.js の特徴です。

それではさっそく、コードを書き替えていきましょう。

コード書き替え前

変更前の画面はこんな感じで、下側が真っ白な状態です。

変更前のコードはこちら。

// メイン画面
<template>
  <v-responsive fluid class="fill-height mx-auto">
    <v-row>
      <v-col cols="12">
        <v-img src="@/assets/pc_room2_1-400x225.jpg" height="60vh" cover></v-img>
      </v-col>
    </v-row>
  </v-responsive>
</template>

<script setup lang="ts">
import SectionCard from './SectionCard.vue'
</script>

コード書き替え

まずは新しいファイル SectionCard.vue を作ります。

// SectionCard.vue
<template>
  <v-container class="pa-0" fluid>
    <v-card class="custom-card" width="300">
      <v-img :src="imageUrl" height="200" cover class="card-image">
        <div class="overlay-content">
          <h2 class="text-white font-weight-bold">{{ title }}</h2>
          <v-btn color="white" variant="outlined" class="mt-2">
            VIEW MORE <v-icon end>mdi-arrow-right</v-icon>
          </v-btn>
        </div>
      </v-img>
    </v-card>

    <div class="description-outside">{{ description }}</div>
  </v-container>
</template>

<script setup lang="ts">
import { computed } from 'vue'

const props = defineProps({
  title: {
    type: String,
    required: true,
  },
  imagePath: {
    type: String,
    required: true,
  },
  description: {
    type: String,
    required: true,
  },
})

const imageUrl = computed(() => new URL(`../assets/${props.imagePath}`, import.meta.url).href)
</script>
// スタイルは省略

続いてメイン画面のコードを以下のように変更します。
赤字が変更箇所

// メイン画面
<template>
  <v-responsive fluid class="fill-height mx-auto">
    <v-row>
      <v-col cols="12">
        <v-img src="@/assets/pc_room2_1-400x225.jpg" height="60vh" cover></v-img>
      </v-col>
    </v-row>
    <v-row justify="center" class="mt-4">
      <v-col cols="auto">
        <SectionCard
          title="NEWS"
          imagePath="superman_hero.png"
          description="最新の技術でWebサイトを構築します"
        />
      </v-col>
      <v-col cols="auto">
        <SectionCard
          title="SERVICE"
          imagePath="study_daigakusei_woman.png"
          description="システム受託開発から自社開発サービスや運用支援など私たちのサービスは多岐にわたります。"
        />
      </v-col>
      <v-col cols="auto">
        <SectionCard
          title="RECRUIT"
          imagePath="kaigi_inemuri.png"
          description="IT戦略の立案から導入までサポート"
        />
      </v-col>
    </v-row>
  </v-responsive>
</template>

<script setup lang="ts">
import SectionCard from './SectionCard.vue'
</script>

するとこんな感じで、 3 つのエリアが表示できます。

解説

最初に作った SectionCard.vue は、「NEWS」「SERVICE」などの 1 つのエリアを構成するコンポーネントです。

このコンポーネントでは、四角い枠組みに背景画像・タイトル・ VIEW MORE ボタンを表示し、枠の下に説明文を表示することだけを定義しています。

ただしこのコンポーネントには、「NEWS」「SERVICE」「最新の技術で…」といった具体的な文言や画像は定義していません。

ではどうやって文字や画像を切り替えているのでしょうか?

答えは props にあります。
const props = defineProps({
title: {
type: String,
required: true,
},
imagePath: {
type: String,
required: true,
},
description: {
type: String,
required: true,
},
})

このように定義することで、コンポーネントを利用する際に title , imagePath , description の具体的な内容を指定でき、表示内容を動的に変更できます。

      <v-col cols="auto">
        <SectionCard
          title="NEWS"
          imagePath="superman_hero.png"
          description="最新の技術でWebサイトを構築します"
        />

2 つ目、 3 つ目のエリアも同様に値を渡すだけで、まったく同じレイアウトで異なる内容のパーツが簡単に作成できます。

まとめ

ここまでの説明で皆さんお察しの通り、コンポーネントの最大のメリットは画面内で何度も登場する部品を再利用できることにあります。

例えばチャットや SNS の「顔写真+氏名」やブログ一覧の「タイトル+本文の冒頭」など、同じレイアウトの部品が何度も登場する場面は多いですよね。

これらを 1 つずつ作るよりも 1 つだけ作って使い回すことで、開発のスピードもぐっと上がります。それでは次回も、魅力的なページ作りに挑戦していきます。お楽しみに!