[Vue.js] 컴포넌트 - 기초

OROSY·2021년 5월 3일
0

Vue.js

목록 보기
21/30
post-thumbnail
post-custom-banner

컴포넌트 기초

지금부터 Vue.js의 중요한 요소 중 하나인 컴포넌트에 대해 알아보도록 합시다. 처음이니만큼 기초에 대해 배우며, 더욱 자세한 사항은 공식 문서를 참고해주시기 바랍니다.

1. 컴포넌트 기본 구성

1.1 App.vue

<template>
  <MyBtn /> // 컴포넌트 렌더링
</template>
<script>
import MyBtn from '~/components/MyBtn' // MyBtn.vue 파일 가져오기

export default {
  components: {
    MyBtn // 가져온 컴포넌트 내부에서 사용할 수 있도록 내보내기
  }
}
</script>

1.2 MyBtn.vue

<template>
  <div class="btn">
    Apple
  </div>
</template>
<style scoped>
  .btn {
    display: inline-block;
    margin: 4px;
    padding: 6px 12px;
    border-radius: 4px;
    background-color: gray;
    color: white;
    cursor: pointer;
  }
</style>

2. 컴포넌트의 특징

2.1 재활용

<template>
  <MyBtn />
  <MyBtn />
  <MyBtn />
</template>

컴포넌트의 장점이라고 한다면, 컴포넌트는 얼마든지 반복해서 재사용할 수 있다는 것입니다. App.vue 파일에 위와 같이 작성한다면 버튼을 재활용하여 여러 개를 화면에 출력할 수 있기 때문입니다.

2.2 Props

또한, 이렇게 재활용을 하면서 props라는 개념을 이용하여 App.vue라는 부모 컴포넌트에서 MyBtn.vue라는 자식 컴포넌트로 데이터를 전달할 수 있습니다.

이러한 이유로 props를 통해 구현한 이 기능을 부모 컴포넌트와 자식 컴포넌트 간의 데이터 통신 방법이라고도 이야기합니다.

App.vue

<MyBtn color="royalblue" />

MyBtn.vue

<div :style="{ backgroundColor: color }" class="btn"> // 데이터 바인딩
    Apple
</div>
export default {
  props: {
    color: { // 외부에서 color 값을 지정할 때 받을 수 있게 함
      type: String,
      default: 'gray' // 기본값 지정
    }
  }
}

2.3 Props로 클래스 추가

이번에는 props를 이용해 클래스를 추가해보도록 합시다.

App.vue

<!-- <div class ="large btn"> -->
<MyBtn large />
<!-- <div class ="btn"> -->
<MyBtn large />

부모 컴포넌트에는 large라는 속성을 별도의 값이 없도록 추가해줍니다.

MyBtn.vue

<div :class="{ large }" class="btn"> Apple </div>
export default {
  props: {
    large: {
      type: Boolean,
      default: false
    }
  }
}

위와 같이 props에 속성 large 객체 리터럴 안으로 type으로 불린 데이터를 지정하고, default 값으로 large라는 속성이 없도록 false를 지정해줍니다.

그러면 위처럼 클래스에 large가 추가되어있고, 그렇지 않은 버튼은 포함되어 있지 않은 것을 확인할 수 있습니다.

2.4 Props로 text 입력

props를 이용하면 text의 내용 또한 입력이 가능합니다.

App.vue

<MyBtn text="Banana" />
<MyBtn :color="color" />
<MyBtn large color="royalblue" />
<MyBtn />

MyBtn.vue

<div class="btn"> {{ text }} </div>
export default {
  props: {
    text: {
      type: String,
      default: '' // 기본값은 공백
    }
  }
}

위처럼 MyBtn의 text 속성에 추가한 값이 버튼 안의 내용으로 입력되게 됩니다. 하지만 이를 화면에 출력하게 되면, 문제점을 발견하게 됩니다.

바로 위와 같이 text 속성을 추가하지 않은 개체는 컨텐츠 내용이 출력되지 않게 됩니다. 당연하게도 Vue.js에서는 해결 방법을 제공하며, slot이라는 개념입니다.

3. Slot

text를 속성으로 넣게 되면, 위와 같은 문제가 발생하였습니다. 그렇다면 이를 해결하기 위해 html에서 <button>text<button>처럼 컨텐츠 내용으로 직접 텍스트를 입력하는 방법을 활용해보도록 합시다.

App.vue

<MyBtn>Banana</MyBtn>
<MyBtn :color="color">Apple</MyBtn>
<MyBtn large color="royalblue">Cherry</MyBtn>
<MyBtn>Orange</MyBtn>

이처럼 부모 컴포넌트에 빈 태그가 아닌 열리고 닫히는 태그의 형태로 표시해줍니다. 그리고 그 안에는 컨텐츠로 들어가는 내용을 입력해줍니다.

MyBtn.vue

<div class="btn">
    <slot></slot> // 컨텐츠 자리 표시
</div>
// 내용 삭제
// export default {
//   props: {
//    text: {
//      type: String,
//      default: ''
//    }
//  }
// }

그리고 버튼 안에 입력할 컨텐츠의 자리를 표시를 해줘야하겠죠? 이 때 바로 slot 태그를 사용합니다. 그렇다면, 이제 위처럼 props에 입력했던 text 내용은 필요가 없으니 삭제해버립니다.

App.vue

<MyBtn :color="color">
  <span style="color: red">Banana</span>
</MyBtn>

덧붙여, slot 태그에는 단순히 text만 입력하는 것이 아니라 자식 컴포넌트가 실행되는 부분에서 열리고 닫히는 태그 사이에 있는 모든 내용을 slot이라는 태그 부분으로 대체하여 넣어준다는 개념입니다. 이를 통해 위처럼 span 태그 안에 text를 입력하고, 스타일까지 적용을 할 수가 있는 것입니다.

위처럼 아주 잘 출력이 됩니다 :D

profile
Life is a matter of a direction not a speed.
post-custom-banner

0개의 댓글