인물 카드 만들기 및 상세 정보 보기
ㆍ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 값을 받아옵니다. 이를 통해 부모 컴포넌트는 자식 컴포넌트에 데이터를 전달할 수 있습니다.
프롭스의 역할
- 데이터 전달: 부모 컴포넌트에서 자식 컴포넌트로 데이터를 전달하여 컴포넌트 간의 상태를 공유할 수 있습니다.
- 컴포넌트 재사용성: 프롭스를 사용하면 컴포넌트를 더 유연하고 재사용 가능하게 만들 수 있습니다. 다른 데이터로 여러 인스턴스를 만들 수 있기 때문입니다.
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>
프롭스를 이용한 데이터 흐름 요약
- 부모 컴포넌트 (Members.vue): showDetailManager 메서드를 통해 클릭된 카드의 이름을 clickedCard 데이터 속성에 저장하고, DetailManager 컴포넌트에 clickedCard를 프롭스로 전달합니다.
- 자식 컴포넌트 (DetailManager.vue): props를 통해 전달받은 clickedCard를 이용해 해당 카드의 상세 정보를 표시합니다.
- 이러한 구조를 통해 부모와 자식 컴포넌트 간의 데이터 흐름을 관리할 수 있습니다.