인물 카드 만들기 및 상세 정보 보기

Project Diary/Vue (Roblox WebSite)

 Vue.js를 이용해 인물 카드를 만들고, 클릭 시 상세 정보 창이 나타나도록 구현하는 방법 기록


1. 인물 카드 컴포넌트 (Manager.vue)

 

1-1 HTML 구조 설정

<template>
  <section class="row">
    <h2 :class="{ dark: changeDarkMode }">
      {{ $t("[5].manager.leadership") }}
    </h2>
    <div class="card__wrapper">
      <div
        class="card"
        :class="{ dark: changeDarkMode }"
        v-for="(item, index) in cardData"
        :key="index"
      >
        <div class="card__media__wrapper">
          <div class="image" :data-category="$t(item.position)">
            <img :src="item.img" :alt="item.name" />
          </div>
        </div>
        <h3>{{ $t(item.name) }}</h3>
        <p>{{ $t(item.content) }}</p>
        <button @click="showDetailManager(item.name)">
          {{ $t("[5].manager.readmore") }}
        </button>
      </div>
    </div>
  </section>
</template>

위의 템플릿에서는 v-for 디렉티브를 사용해 cardData 배열을 순회하며 각 인물 카드를 생성합니다. 각 카드에는 이미지, 이름, 간단한 설명, 그리고 '자세히 보기' 버튼이 포함됩니다.

 

1-2 데이터 설정 및 메서드 정의

 

<script>
export default {
  name: "Manager",
  data() {
    return {
      cardData: [
        {
          img: "./assets/images/members-1/managers/Dave_Baszucki_Thumbnail_Large.jpg",
          position: "[5].detailmanager.first-position",
          name: "[5].detailmanager.first-name",
          content: "[5].detailmanager.first-content",
        },
        // 더 많은 인물 데이터...
      ],
    };
  },
  computed: {
    changeDarkMode() {
      return this.$store.getters.fnGetDark;
    },
  },
  methods: {
    showDetailManager(name) {
      this.$emit("showDetailManager", name); // 'showDetailManager' 이벤트를 부모 컴포넌트에 전달
    },
  },
};
</script>

 

 

2.  상세 정보 컴포넌트 (DetailManager.vue)

 

2-1 HTML 구조 설정

 

<template>
  <section class="row" id="detailView">
    <div class="detail__wrapper">
      <div v-for="(detailItem, index) in detailCardData" :key="index">
        <div class="detail__card" v-if="clickedCard === detailItem.name">
          <img :src="detailItem.img" :alt="detailItem.name" />
          <h3>{{ $t(detailItem.name) }}</h3>
          <span>{{ $t(detailItem.position) }}</span>
          <div class="all__content">
            <p>{{ $t(detailItem.content) }}</p>
            <br />
            <br />
            <p>{{ $t(detailItem.detail1) }}</p>
            <br />
            <br />
            <p>{{ $t(detailItem.detail2) }}</p>
          </div>
          <button @click="closeDetail">
            {{ $t("[5].detailmanager.close") }}
          </button>
        </div>
      </div>
    </div>
  </section>
</template>

 

2-2 데이터 설정 및 메서드 정의

상세 정보를 표시하기 위한 데이터를 설정하고, 상세 정보 창을 닫는 메서드를 정의합니다.

 

<script>
export default {
  name: "DetailManager",
  props: ["clickedCard"], // 'clickedCard'를 부모 컴포넌트로부터 props로 받음
  data() {
    return {
      detailCardData: [
        {
          img: "./assets/images/members-1/managers/Dave_Baszucki_Thumbnail_Large.jpg",
          position: "[5].detailmanager.first-position",
          name: "[5].detailmanager.first-name",
          content: "[5].detailmanager.first-content",
          detail1: "[5].detailmanager.first-detail1",
          detail2: "[5].detailmanager.first-detail2",
        },
        // 더 많은 상세 인물 데이터...
      ],
    };
  },
  methods: {
    closeDetail() {
      this.$emit("closeDetail"); // 'closeDetail' 이벤트를 부모 컴포넌트에 전달
    },
  },
};
</script>

 

 

3. 프롭스 (Props)

Vue.js에서 **프롭스(Props)**는 부모 컴포넌트가 자식 컴포넌트에 데이터를 전달하는 데 사용되는 중요한 메커니즘입니다. 

이 프로젝트에서 DetailManager 컴포넌트는 props를 통해 부모 컴포넌트로부터 clickedCard 값을 받아옵니다. 이를 통해 부모 컴포넌트는 자식 컴포넌트에 데이터를 전달할 수 있습니다.

 

프롭스의 역할

  1. 데이터 전달: 부모 컴포넌트에서 자식 컴포넌트로 데이터를 전달하여 컴포넌트 간의 상태를 공유할 수 있습니다.
  2. 컴포넌트 재사용성: 프롭스를 사용하면 컴포넌트를 더 유연하고 재사용 가능하게 만들 수 있습니다. 다른 데이터로 여러 인스턴스를 만들 수 있기 때문입니다.

 

4. 상위 컴포넌트 (Members.vue)

상위 컴포넌트에서 Manager와 DetailManager 컴포넌트를 사용하고, 인물 카드 클릭 시 상세 정보를 표시하도록 구현합니다.

 

<template>
  <div>
    <manager
      v-if="showManager"
      class="manager"
      @showDetailManager="showDetailManager"
      :clickedCard.sync="clickedCard"
      :class="{ active: showDetail }"
    />
    <detail-manager
      class="detailManager"
      :clickedCard.sync="clickedCard"
      :class="{ active: showDetail }"
      @closeDetail="closeDetail"
    />
  </div>
</template>

 

4-1 데이터 설정 및 메서드 정의

 

<script>
import Manager from "@/components/members/Manager.vue";
import DetailManager from "@/components/members/DetailManager.vue";

export default {
  name: "Members",
  components: { Manager, DetailManager },
  data() {
    return {
      showManager: true,
      showDetail: false,
      clickedCard: "", // 클릭된 카드의 이름을 저장
    };
  },
  methods: {
    showDetailManager(name) {
      this.showDetail = true;
      this.clickedCard = name; // 클릭된 카드의 이름을 설정
    },
    closeDetail() {
      this.showDetail = false;
    },
  },
};
</script>

 

 

프롭스를 이용한 데이터 흐름 요약

  1. 부모 컴포넌트 (Members.vue): showDetailManager 메서드를 통해 클릭된 카드의 이름을 clickedCard 데이터 속성에 저장하고, DetailManager 컴포넌트에 clickedCard를 프롭스로 전달합니다.
  2. 자식 컴포넌트 (DetailManager.vue): props를 통해 전달받은 clickedCard를 이용해 해당 카드의 상세 정보를 표시합니다.
  3. 이러한 구조를 통해 부모와 자식 컴포넌트 간의 데이터 흐름을 관리할 수 있습니다.