Vue) 07. component로 쪼개기..

준영·2022년 7월 29일
1

컴포넌트의 장점)

  • 재사용에 용이하다!
  • 유지보수가 쉽다!
  • 코드가 짧이지며 심미적으로도 좋다!

컴포넌트로 만들기)

App.vue에 있는 다음과 같은 할인 배너를 컴포넌트로 빼서, 사용하도록 하겠다.

HTML)

<div class="discount">
  <h4>지금 결제하시면, 10% 할인!!</h4>
</div>

CSS)

.discount {
  background: #eee;
  padding: 10px;
}

  1. 우선 src/components라는 폴더 안에 DiscountBanner.vue라는 파일을 생성해주었다.


  1. 그 다음에 App.vue와 같은 양식의 구조를 만들어주었다.
  • 확장프로그램을 설치했다면, < 입력 후 Enter를 누르면 바로 vue의 구조가 완성이 된다!


  1. 템플릿 부분에는 아까 만들었던 HTML코드를 작성하고, 스크립트 부분에는 컴포넌트의 이름을 작성해주면 컴포넌트 완성!

💡 이제 컴포넌트.vue 이름은 귀찮게 2단어 이상으로 작명해야합니다 안그러면 에러로 잡혀요!!

  • DiscountBanner.vue 이런 식으로 2단어로 작명 잘하면 됩니다.
<template>
  <!-- 배너 광고 -->
  <div class="discount">
    <h4>지금 결제하시면, 10% 할인!!</h4>
  </div>
</template>

<script>
export default {
  name: "DiscountBanner",
};
</script>

<style></style>

  1. 다시 컴포넌트를 불러서 사용할 App.vue로 돌아가서 사용하기 위한 준비를 해야하는데..
<script>
import products from "./assets/data";
import DiscountBanner from "./components/DiscountBanner.vue";

export default {
  name: "App",
  // 데이터 저장함 (변수선언)
  data() {
    return {
      products,
      menus: ["Home", "Products", "About"],
      modalOpen: false,
      clickValue: null,
    };
  },
  // 힘수저장함 (함수선언)
  methods: {},
  components: {
    DiscountBanner: DiscountBanner,
  },
};
</script>
  • App.vue의 스크립트 부분에서 컴포넌트를 Import한다.
  • Components 부분에서 오른쪽에는 전에 우리가 불러 올 컴포넌트에 이름, 왼쪽에는 불러온 컴포넌트를 부를 이름이다.

    둘다 이름이 같게 할 경우에는 DiscountBanner하나로 생략이 가능하다!


  1. 마지막으로 App.vue 템플릿 부분에 앞으로 부를 이름으로 컴포넌트를 호출하게 되면 끝!
<!-- 배너 광고 -->
<!-- <div class="discount">
    <h4>지금 결제하시면, 10% 할인!!</h4>
  </div> -->
<!-- 배너 광고 컴포넌트 예제 -->
<DiscountBanner />

출력결과)

🙋🏻‍♂️ App.vue에 메뉴바 아래와 모달창 안쪽에 컴포넌트를 재사용했다.


App.vue 전체 코드)

<template>
  <!-- 모달창 -->
  <div class="black-bg" v-if="modalOpen === true">
    <div class="white-bg">
      <img :src="products[clickValue].image" class="room-img" />
      <h3>{{ products[clickValue].title }}</h3>
      <p>{{ products[clickValue].content }}</p>
      <p>{{ products[clickValue].price }} ₩</p>
      <DiscountBanner />
      <button v-on:click="modalOpen = false" class="modal-exit-btn">
        닫기
      </button>
    </div>
  </div>

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

  <div v-else>
    <p>안녕못하세요</p>
  </div> -->

  <!-- 헤더 -->
  <div class="menu">
    <a v-for="(el, index) in menus" :key="index">{{ el }}</a>
  </div>

  <!-- 배너 광고 -->
  <!-- <div class="discount">
    <h4>지금 결제하시면, 10% 할인!!</h4>
  </div> -->
  <!-- 배너 광고 컴포넌트 예제 -->
  <DiscountBanner />

  <!-- 상품리스트 -->
  <div v-for="(el, index) in products" :key="index">
    <img v-bind:src="el.image" class="room-img" />
    <h4
      v-on:click="
        modalOpen = true;
        clickValue = index;
      "
      class="product-name"
    >
      {{ el.title }}
    </h4>
    <p>{{ el.price }} ₩</p>
    <!-- <button v-on:click="el.report++">허위매물신고</button>
    <span>신고수: {{ el.report }}</span> -->
  </div>
</template>

<script>
import products from "./assets/data";
import DiscountBanner from "./components/DiscountBanner.vue";

export default {
  name: "App",
  // 데이터 저장함 (변수선언)
  data() {
    return {
      products,
      menus: ["Home", "Products", "About"],
      modalOpen: false,
      clickValue: null,
    };
  },
  // 힘수저장함 (함수선언)
  methods: {},
  components: {
    DiscountBanner: DiscountBanner,
  },
};
</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 {
  display: flex;
  align-items: center;
  width: 100%;
  height: 100%;
  background-color: rgba(0, 0, 0, 0.5);
  position: fixed;
  padding: 20px;
}

.white-bg {
  width: 100%;
  background-color: white;
  padding: 20px;
  border-radius: 8px;
}

.modal-exit-btn {
  margin-top: 30px;
}

.modal-exit-btn:hover {
  cursor: pointer;
}

.menu {
  background: darkslateblue;
  padding: 15px;
  /* border-radius: 5px; */
}

.menu a {
  color: white;
  padding: 10px;
}

.room-img {
  width: 100%;
  margin-top: 40px;
}

.product-name {
  cursor: pointer;
}

.product-name:hover {
  text-decoration: underline;
}

.discount {
  background: #eee;
  padding: 10px;
}
</style>

앞으로의 문제)

위에 코드를 보면 알겠지만, 모달창을 컴포넌트로 방금 방법으로 만들어주면 작동을 하지않는다.

이유는 모달에 바인딩 되어있는 데이터가 모달창 컴포넌트 스크립트 부분에 없기 때문이다.

이러한 문제를 해결하기 위해 Props를 배우고 올게연..🥲

profile
개인 이력, 포폴 관리 및 기술 블로그 사이트 👉 https://aimzero-web.vercel.app/

0개의 댓글