[Vue] 컴포넌트- 속성, 상속

youngseo·2022년 5월 2일
0
post-thumbnail

한 번에 끝내는 프론트엔드 개발 초격차 패키지 Online를 들으며 정리한 내용입니다.

컴포넌트- 속성 상속

1. 속성 상속

1-1 클래스 상속

부모 컴포넌트의 html 요소에 class나 기타 속성들이 자식 컴포넌트의 하나의 요소에 연결되는 것을 속성 상속이라고 합니다.
App.vue

<template>
  <MyBtn class="heory" style="color: red">
    Banana
  </MyBtn>
</template>
<script>
import MyBtn from '~/components/MyBtn'

export default {
  components: {
    MyBtn
  }
}
</script>

MyBtn.vue

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

개발자도구를 열어 확인해보면, 부모 컴포넌트의 MyBtn에 해당하는 클래스 속성의 값과 스타일이 해당하는 자식 컴포넌트의 div부분에 적용이 되었음을 알 수 있습니다.

1-2 상속 주의사항

여기서 주의해야할 부분이 있습니다. 하나의 컴포넌트 같은 경우template태그 사이에 하나의 html구조를 작성하게 됩니다. 이 템플릿의 바로 자식요소를 해당하는 컴포넌트의 최상위 요소(루트요소)라고 부릅니다.

<template>
  <div class="btn">  //최상위 요소(루트요소)
    <slot></slot>
  </div>
  <div></div>  //최상위 요소(루트요소)
</template>

위와 같이 자식 컴포넌트에 div요소를 하나 더 추가를 하면 MyBtn이라는 컴포넌트는 최상위요소가 2개가 있는 상태가 되게 되어, 부모 컴포넌트에 입력한 속성 값이 어느 부분에 상속이 되어야하는지 판단할 수 없기 때문에 두 요소 모두 상속이 되지 않게 됩니다.

따라서 자식 컴포넌트의 최상위요소가 2개가 있는 경우 부모 컴포넌트에 입력한 속성의 내용들이 자식 컴포넌트의 어느 부분에 상속이 되어야하는지를 정의해주어야합니다.

2 inheritAttrs

자식 컴포넌트의 script부분에 속성의 상속을 지정해주는 옵션인inheritAttrs속성을 이용해 하나의 방식으로 정리를 해줄 수 있습니다.
MyBtn.vue

<script>
export default {
  inheritAttrs: false
}
</script>

inheritAttrs: false 값을 준 후 확인을 해보면 최상위요소가 하나밖에 없음에도 부모 컴포넌트에 입력한 속성들이 상속되고 있지 않은 것을 확인할 수 있습니다.

이렇게 inheritAttrs: false 을 통해 처음부터 어떠한 속성들도 상속하지 않는 상태로 만든 후 프로젝트를 시작할 수 있습니다.

3 created

이러한 옵션이 추가되어 있거나 최상위 요소가 여러개가 있어서 속성상속을 받을 수 없는 구조에서, 부모 컴포넌트에 작성되어 있는 여러가지 속성들을 특정한 요소에다 직접적으로 연결해주고 싶다면 created라이프사이클과 $attrs객체를 활용할 수 있습니다.
MyBtn.vue

<script>
export default {
  inheritAttrs: false,
  created() {
    console.log(this.$attrs)
  }
}
</script>

created라이프사이클을 통해 컴포넌트가 생성된 직후에 컴포넌트가 가지고 있는 $attrs 특정객체를 출력해볼 수 있습니다.

개발자도구를 확인해보면 하나의 데이터처럼 내용이 구성되어 있는 것을 확인할 수 있습니다.이렇게 부모컴포넌트의 속성의 내용들이 this의 $attrs라는 특정한 객체에 저장되어서 확인을 할 수 있도록 만들어줍니다.

그러면 이러한 내용이 특정한 요소에 적용이 될 수 있도록 만들어줍니다.
MyBtn.vue

<template>
  <div class="btn">
    <slot></slot>
  </div>
  <h1
    :class="$attrs.class"
    :style="$attrs.style"></h1>
</template>

해당 클래스의 값과 스타일이 잘 들어간 것을 확인할 수 있습니다.

이렇게 루트 엘리먼트가 하나 이상이거나, 하나밖에 없을 때 그것을 상속하지 않는 옵션을 정리해준 후에 실제 들어오는 속성들을 원하는 요소에 연결해줄때 $attrs객체를 활용할 수 있습니다.

4. v-bind="$attrs"

또한 이렇게 하나의 요소에 해당하는 내용을 모두 적용하는 경우에는 v-bind속성을 추가해 아래와 같이 작성해주어도 됩니다.

단, v-bind를 :와 같은 약어로 사용해서는 안됩니다.

  <h1 v-bind="$attrs"></h1>

0개의 댓글