관리 메뉴

여름 언덕에서 배운 것

모달창 내에 상세페이지 만들기 본문

가랑비에 옷 젖는 줄 모른다 💻/Vue.js

모달창 내에 상세페이지 만들기

잔뜩 2023. 9. 26. 01:40
<template>
  <div class="menu">

    <div class="black-bg" v-if="모달창열렸니==true">
      <div class="white-bg">
        <h4>{{원룸들[누른거].title}}</h4>
        <p>상세페이지 내용임</p>
        <button @click="모달창열렸니=false">닫기</button>
      </div>
    </div>
    
    <a v-for="작명 in 메뉴들" :key="작명">{{ 작명 }}</a>
  </div>
  <div v-for="(room,i) in 원룸들" :key="i">
    <img :src="room.image" class="room-img" alt="">
    <h4 @click="모달창열렸니=true; 누른거 = i">{{room.title}}원룸</h4>
    <p>{{room.price}}</p>
  </div>
</template>

<script>
import data from './assets/oneroom';

export default {
  name: 'App',
  data() { 
    return {
      누른거 : 0,
      원룸들 : data,
      //products: ['신촌', '낙성대', '송파'],
      신고수 : [0,0,0],
      메뉴들 : ['Home','Shop','About'],
      모달창열렸니 : false
    }
  },  
  methods: {
    increase(index) { 
      this.신고수[index] += 1;
    }
  },
  components: {
  
  }
}
</script>

<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
}
body{
  margin : 0
}
div{
  box-sizing: border-box;
}
.black-bg{
  width: 100%; height: 100%;
  background: rgba(0,0,0,0.5);
  position: fixed; padding : 20px;
}
.white-bg{
  width: 100%; background: white;
  border-radius: 8px;
  padding: 20px;
}
.room-img{
  width : 100%;
  margin-top: 40px;
}
.menu{
  background:  darkslateblue;
  padding: 15px;
  border-radius: 5px;
}
.menu a {
  color: white;
  padding: 10px;
}

</style>

오늘의 5분 숙제 : 

오늘 만들었던 모달창 내의 내용을 알아서 꾸며보시길 바랍니다. 

대충 상품명, 상품설명, 가격, 이미지 정도만 기입하면 됩니다. 

 

 

저번시간 숙제는 어떻게 했냐면

저는 이렇게 했다고 합니다.

 

<div v-for="(a, i) in 원룸들" :key="i">
  <img :src="a.image" class="room-img">
  <h4 @click="모달창열렸니 = true">{{a.title}}</h4>
  <p>{{a.price}}</p>
</div>

 

 

원룸들을 반복문 돌려버리면 

1. 원룸들 안에 있던 자료 갯수만큼 반복문이 됩니다. <div>가 6회 생성되겠군요.

2. 첫째 작명한 a라는 변수는 안에 있던 자료가 됩니다. {} 이거가 되겠군요. 

그리고 제목을 누르면 모달창 여는 코드도 작성해놨습니다. 

 

[collapse]

 

 

일단 상품제목 누르면 모달창 띄우는 코드 부터 다시 작성해봅시다.

모달창을 만들었는데 내용이 아무것도 없군요.

여기에 실제 상품의 상세내용을 출력해주고 싶습니다. 

 

첫째 상품을 누르면 첫째 상품의 제목, 가격, 설명 

둘째 상품을 누르면 첫째 상품의 제목, 가격, 설명

...

이렇게 모달창 안에 출력하려면 코드를 어떻게 짜면 될까요?

실은 저번에 모달창만들 때 했던 2-step 그대로 적용해보셔도 가능합니다. 

 

 

 

0번상품을 누르면 0번제목이 모달창안에 떠야합니다

 

저번 모달창을 이렇게 수정하면 되는게 아닐까요

<div class="black-bg" v-if="모달창열렸니 == true">
  <div class="white-bg">
    <h4>{{ 원룸들[0].title }}</h4>
    <p>상세페이지내용임</p>
  </div>
</div>

이렇게 작성하면 원룸들데이터 [ {}, {}, {}, {}, {}, {} ] 중에 0번째 제목이 저기 모달창에 박히겠죠.

근데 0번째 제목 맞습니까? 아마 이렇게 되어야하지 않을까요.

 

 

<div class="black-bg" v-if="모달창열렸니 == true">
  <div class="white-bg">
    <h4>{{ 원룸들[누른거].title }}</h4>
    <p>상세페이지내용임</p>
  </div>
</div>

사용자가 방금 누른 상품번호를 여기 넣어야겠군요.

그니까 1번상품 누르면 1이 되는 변수

2번상품 누르면 2가 되는 변수를 넣자는 겁니다.

그럼 모달창이 완성될 듯 합니다. 

그래서 누른거라는 데이터를 밑에다가 신설했습니다.

 

 

data(){
  return {
    누른거 : 0
  }
}

여기다가 "사용자가 누른 상품번호"를 저장하기로 했고

이게 1로 바뀌면 1번상품제목, 2로 바뀌면 2번상품제목이 모달창에 잘 보이겠네요 

 

 

 

그럼 이제 뭐해야합니까

사용자가 1번상품제목 누르면 저거 누른거를 1로 바꾸면 되는거 아니겠습니까. 

 

<div v-for="(a, i) in 원룸들" :key="i">
  <img :src="a.image" class="room-img">
  <h4 @click="모달창열렸니 = true; 누른거 = i">{{a.title}}</h4>
  <p>{{a.price}}</p>
</div>

각 상품명을 누르면 누른거도 바뀌도록 만들어놨습니다.

X번상품 제목을 누르면 누른거가 X로 바뀝니다.

 

 

 

총 정리를 하자면 

1. X번상품을 누르면 누른거라는 data가 X로 바뀜

2. 그럼 모달창 안에 {{ 원룸들[누른거].title }} 이것도 실시간 재렌더링됨 (관련된 data가 바뀌었으니까요)

3. 그럼 모달창 제목이 {{ 원룸들[X].title }} 이렇게 나옵니다.

 

 

어떻게 보면 저번시간 UI만드는 2-step이랑 비슷합니다.

상세페이지도 일종의 UI라고 볼 수 있기 때문에

1. 상세페이지UI 상태를 미리 저장해두고

2. 그 상태에 따라 HTML이 어떻게 보일지 작성

그럼 스위치가 완성됩니다.

그리고 필요할 때 버튼누르면 스위치 껐다켜고 그러면 된다고 했습니다. 

 

 

 

 

 

v-else 라는 문법도 있습니다

 

v-if="" 는 조건식이 참일 경우에만 특정 HTML을 보여줄 수 있다고 했습니다.

근데 v-else 이런 것도 있습니다.

<div v-if="1 == 2">
  안녕하세요
</div>
<div v-else>
  안녕하세요2
</div>

v-if 에 적은 조건식이 참이 아닐 경우에 v-else를 보여줍니다. 

 

조건에 따라서 이거 혹은 저거를 보여주고 싶을 때 사용합니다.

 

 

<div v-if="1 == 2">
  안녕하세요
</div>
<div v-else-if="1 == 3">
  안녕하세요2
</div>

자바스크립트 else if 문법처럼 

조건식을 연달아서 두개 세개 검사해보고 싶을 때 사용하시면 되겠습니다. 

참고하시고 숙제로 모달창 내용이나 멋있게 완성해오도록 합시다. 

728x90