VueJS에서 하위 컴포넌트로 데이터를 전달하는 방법도 있지만
원하는 템플릿, 태그 등을 추가하는 것도 가능합니다. 이 경우 잘 알려진 방법으로 slot을 사용하는 방법이 있습니다. 아래는
VueJS에서 slot을 사용하는 방법에 대하여 알아보려고 합니다.
# VueJS에서 하위 컴포넌트에 태그 전달하기
공식 웹사이트를 찾아보니 기존의 slot을 사용하는 방법식 구현이 가능하기는 하지만 deprecated 되었으므로 v-slot을 사용하라고 하니 참고하시기 바랍니다. 여기서도
v-slot을 사용하는 방법을 알아보겠습니다. 그리고
slot의 존재 여부를 확인하여 방법도 같이 알아봅니다.
@ slot 또는 v-slot을 사용하는 무엇을 할 수 있을까요?
이미 아시는 경우 다음의 v-slot으로 넘어가셔도 됩니다. slot 또는 v-slot의 사용 목적은 만약 각각의 하위 컴포넌트 마다 다른 아이콘을 추가하고 싶을때가 좋은 예입니다. 즉 아래와 같이 각각 다른 아이콘을 적용하는 것이 가능하게 됩니다.
<ParentComponent>
<template>
<div>
<ChildAComponent>
<i class="icon icon-arrow" />
</ChildAComponentA>
<ChildBComponent>
<i class="icon icon-close" />
</ChildBComponent>
</div>
</template>
</ParentComponent>
여기서는 부모 컴포넌트가 각각의 ChildA와 ChildB 컴포넌트에 서로 다른 icon 클래스를 가진 태그를 전달하였습니다. 위 예제는 일반적인 slot 사용의 목적입니다. v-slot의 경우 slot 자체에 이름을 추가할 수 있는데 이처럼
이름을 사용할 경우 하나의 컴포넌트에서도 body, footer처럼 나누어서 전달하는 것이 가능하게 됩니다.
! v-slot을 사용하는 방법
이제
v-slot을 사용하는 방법부터 알아봅니다. 상위 컴포넌트에서는 하위로 전달할 경우 template 태그를 사용하되 v-slot 어트리뷰트에 slot이름을 사용하여 하위 컴포넌트에 전달해야 합니다.
<template v-slot:(이름)></template>
여기서 사용된 v-slot의 이름은 전달받은 자식 컴포넌트에서 해당 요소를 어디에 적용할 지 구분하는데 사용됩니다.아래는 간단한 예제로 이렇게 사용한다고 보시면 됩니다. 먼저 부모 요소에서 footer 이름의 v-slot을 만들어 전달할 경우입니다. 이때도 template을 사용합니다.
<div>
...
<ChildComponent>
<template v-slot:footer>
<span>webisfree.com</span>
</template>
</ChildComponent>
</div>
이제 하위 컴포넌트 ChildComponent에서는 v-slot을 사용하여 전달 받게 됩니다. 이때 name 속성에 해당하는 slot 이름 footer를 사용합니다.
<div class="footer">
...
<slot name="footer" />
</div>
위 예제처럼 v-slot을 사용하는 방법은 간단합니다. 추가로
만약 하나의 컴포넌트에 footer 외에 다른 v-slot도 전달하려면 어떻게 하는지 알아봅니다.
! 하위 컴포넌트에 v-slot 여러 개 사용하기
v-slot을 사용할 경우 여러 개의 template을 각기 다른 이름으로 사용할 수 있다고 알았는데요 이를 자식 요소에 전달하여 여러개의 slot을 전달(multiple slots)하는 것이 가능하죠. 예를들어 아래는 body, footer 두 개를 사용한 예제입니다.
<div>
<template v-slot:body>
<h3>Welcome to Webisfree.com</h3>
</template>
<template v-slot:footer>
<h3>Webisfree.com</h3>
</template>
</div>
두 개의 template을 사용하였습니다. 이제 아래와 같이 하위 컴포넌트에서 body, footer로 나누어 전달 받아야겠습니다.
<div class="content">
<div class="body">
<slot name="body" />
</div>
<div class="footer">
<slot name="footer" />
</div>
</div>
이처럼 사용 방법은 매우 간단합니다~ 하나 이상 또는 여러 개의 slot을 전달할 수 있게되었습니다.
! slot의 존재 여부를 확인하는 방법
하위 컴포넌트에서는
slot의 여부에 따라 특정 태그를 보이거나 숨길 필요도 있을 것 입니다. 예를들어 아래의 div 클래스 footer의 경우 footer 이름의 slot이 전달되지 않는다면? 이 경우 굳이 보여줄 필요가 없을 것 입니다. 이때 아래와 같이 적용할 수 있습니다. computed에 isExistFooter라는 값을 하나 선언하여 확인하는 방법입니다.
<template>
<div
v-if="isExistFooter"
class="footer"
>
<slot name="footer" />
</div>
</template>
<script>
export default {
computed: {
isExistFooter: function() {
return this.$slots.footer ? true : false;
}
},
...
}
</script>
위 예제는 살펴보면 computed 내부의 함수 isExistFooter는 this.$slots를 사용하였습니다. 여기서
$slots는 해당 컴포넌트에 사용되는 모든 slots에 접근할 수 있으며 아래처럼 이름으로 접근하는 것도 가능합니다.
return this.$slots.footer ? true : false;
이처럼 this.$slots.footer를 사용하여 footer 이름의 slot의 존재 여부에 따라 true, false의 불리언으로 반환하는 것이 가능하고 이를 사용하여 v-if처럼 분기문에 적용하는 것도 가능합니다.
여기가지 VueJS에서 v-slot을 사용하는 방법에 대하여 몇 가지 방법들을 알아보았습니다.