Vue에서 Slot을 통한 컴포넌트 재사용

Slots

🐔 Slots 기본적인 사용 방법

slot은 컴포넌트의 재사용성을 높여준다.

slot을 통해 하위 컴포넌트를 확장하거나 재정의할 수 있다. 

<!-- 사용하는 쪽 -->
<버튼컴포넌트>구독하기</버튼컴포넌트>
<!-- 버튼컴포넌트.vue -->
<template>
    <button>
    	<slot></slot>
    </button>
</template>

 

slot을 통해 특정 컴포넌트에 콘텐츠를 전달할 수 있다.

콘텐츠를 위치시키고 싶은 곳에 slot 배치하고, 사용하는 쪽에서 콘텐츠를 넣으면 된다.

 

<!-- 최종 -->
<button>구독하기</button>

최종적으로 화면에는 이렇게 구성이 된다.

 

 

🐔 Slot의 Fallback Content 기능

<!-- 버튼컴포넌트.vue -->
<template>
    <button>
    	<slot>기본</slot>
    </button>
</template>

slot은 Fallback Content를 제공하는데 상위 컴포넌트에서 콘텐츠가 적용되지 않을때에 대한 default 콘텐츠를 말한다.

사용하는 방식은 그냥 slot에 작성하면 된다

 

 

🐔 Slot의 Named Slots

slot 요소에 이름을 부여하여 여러개의 slot을 정의하는 것 

 

(1) 자식 컴포넌트

<template>
    <article>
    
        <div>
            <slot name="header"></slot>
        </div>
        
        <div>
            <slot></slot>
        </div>
        
        <div">
            <slot name="footer"></slot>
        </div>
        
    </article>
</template>

이름을 통해 부모 컴포넌트에서 어느 슬롯 콘텐츠에 넣을지 위치를 설정할 수 있다.

이름이 없으면 디폴트가된다.

 

(2) 부모 컴포넌트

<template>
    <BaseCard>
    
        <template v-slot:header>제목</template>
        <template v-slot:default>안녕하세요</template>
        <template v-slot:footer>푸터</template>
        
    </BaseCard>
</template>

v-slot:전달인자를 사용하여 지정한 슬롯 콘텐츠에 전달할 수 있다.

 

(3) 부모 컴포넌트 단축 표현

<template>
    <BaseCard>
    
        <template #header>제목</template>
        <template #default>안녕하세요</template>
        <template #footer>푸터</template>
        
    </BaseCard>
</template>

v-slot은 #으로 단축 표현할 수 있다.

 

(4) Dynamic Slot Named

<BaseCard>

    <template #[dynamicSlotName]>저쩌구</template>
    
</BaseCard>

v-slot 디렉티브 전달인자에 데이터를 바인딩하여 동적으로 변경 가능

 

 

🐔 Slot의 Render Scopte

슬롯 콘텐츠는 상위 컴포넌트에 정의되어있기 때문에 상위 컴포넌트의 데이터 영역은 접근이 가능하지만

하위 컴포넌트의 영역에는 접근할 수 없다.

scopted slots 방법으로 접근이 가능하다 (마치 props 전달하는 것처럼)

 

Scoped Slots

<template>
    <div>
    	<slot :text="greetingMessage" :count="count"></slot>
    </div>
</template>

<script>
    import { ref } from 'vue';
    export default {
        setup() {
            const greetingMessage = ref('전달해주세요');
            const count = ref(1);
            return {
                greetingMessage,
                count,
            };
        },
    };
</script>

슬롯 콘텐츠는 자식 컴포넌트의 데이터에 접근할 수 없지만, props처럼 속성을 슬롯 콘텐츠에 전달할 수 있다.

 

<MyComponent v-slot="slotProps">
	{{ slotProps.text }} {{ slotProps.count }}
</MyComponent>

default slot이 하나 밖에 없는 경우 v-slot 디렉테브를 사용하여 props를 전달 받을 수 있다.

 

Named Scoped Slots

v-slot:name="slotProps”

<MyComponent>

    <template #header="headerProps">
   		{{ headerProps }}
    </template>

    <template #default="defaultProps">
    	{{ defaultProps }}
    </template>

    <template #footer="footerProps">
    	{{ footerProps }}
    </template>
    
</MyComponent>

이름이 부여된 슬롯도 유사하게 동작한다.