zoaseo
To Infinity And Beyond
zoaseo
전체 방문자
오늘
어제
  • 분류 전체보기 (760)
    • 개발이 좋아서 (378)
      • SAP가 좋아서 (0)
      • Java가 좋아서 (42)
      • Spring이 좋아서 (50)
      • JPA가 좋아서 (0)
      • QueryDSL이 좋아서 (26)
      • Docker가 좋아서 (7)
      • Redis가 좋아서 (7)
      • AWS가 좋아서 (5)
      • CI/CD가 좋아서 (6)
      • Troubleshooting이 좋아서 (4)
      • Kotlin이 좋아서 (7)
      • SQL이 좋아서 (6)
      • HTTP가 좋아서 (21)
      • JavaScript가 좋아서 (30)
      • TypeScript가 좋아서 (6)
      • Vue가 좋아서 (21)
      • Flutter가 좋아서 (61)
      • React가 좋아서 (20)
      • Redux(React)가 좋아서 (2)
      • Angular가 좋아서 (22)
      • HTML이 좋아서 (9)
      • CSS가 좋아서 (15)
      • PHP가 좋아서 (9)
      • Illustrator가 좋아서 (2)
    • 노력이 좋아서 (169)
    • 결과물이 좋아서 (14)
    • 코딩연습이 좋아서 (168)
      • 이론이 좋아서 (62)
      • SQL이 좋아서 (90)
    • 유용한 사이트가 좋아서 (28)
    • Github (2)

인기 글

티스토리

hELLO · Designed By 정상우.
zoaseo
개발이 좋아서/Vue가 좋아서

16장 Slots

개발이 좋아서/Vue가 좋아서

16장 Slots

2023. 9. 14. 16:16

1)

HTML 요소와 마찬가지로 우리가 만든 컴포넌트에 콘텐츠를 전달할 수 있으면 유용합니다. <FancyButton> 컴포넌트를 만든 후 콘텐츠를 전달해 보도록 하겠습니다.

<!-- FancyButton.vue -->
<template>
	<button class="fancy-btn">
		<slot></slot>
	</button>
</template>

위에 정의한 컴포넌트를 부모 컴포넌트에서 사용해보겠습니다.

<FancyButton>
	<!-- 슬롯 콘텐츠 -->
	Click!!
</FancyButton>

<slot> 요소는 부모 컴포넌트에서 제공하는 콘텐츠를 나타내는 슬롯 콘텐츠 입니다. 그리고 슬롯은 텍스트 뿐만아니라 HTML요소, 컴포넌트 등 다양한 모든 콘텐츠가 될 수 있습니다.

<FancyButton>
	<!-- 슬롯 콘텐츠 -->
  <span style="color: red">Click me</span>
  <i>!</i>
</FancyButton>

2) Fallback Content

상위 컴포넌트에서 슬롯 콘텐츠가 제공되지 않을때 슬롯에 대한 폴백(기본 콘텐츠)을 지정할 수 있습니다.

<!-- FancyButton.vue -->
<template>
  <button class="btn">
    <slot>Default Click!!</slot>
  </button>
</template>

3) Named Slots

<slot> 요소에 이름을 부여하여 여러개의 <slot>을 정의할 수 있습니다.

<!-- BaseCard.vue -->
<template>
  <article>
    <div>
      <slot name="header"></slot>
    </div>
    <div>
      <slot></slot>
    </div>
    <div">
      <slot name="footer"></slot>
    </div>
  </article>
</template>
  • <slot>에 name속성을 부여하여 특정 슬롯 콘텐츠가 렌더링 되어야 할 위치를 설정할 수 있습니다.
  • name이 없는 <slot>의 이름은 암시적으로 default입니다.
<!-- 부모 컴포넌트 사용 예시 -->
<template>
  <BaseCard>
    <template v-slot:header>제목</template>
    <template v-slot:default>안녕하세요</template>
		<template v-slot:footer>푸터</template>
  </BaseCard>
</template>

위 예시처럼 name이 부여된 <slot>에 콘텐츠를 전달하려면 v-slot 디렉티브를 사용하여 전달할 수 있습니다. 그리고 v-slot:전달인자를 사용하여 지정한 슬롯 콘텐츠에 전달할 수 있습니다.

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

<!-- 부모 컴포넌트 사용 예시 -->
<template>
  <BaseCard>
    <template #header>제목</template>
    <template #default>안녕하세요</template>
		<template #footer>푸터</template>
  </BaseCard>
</template>

그리고 default 슬롯은 암시적으로 처리할 수 있습니다.

<!-- 부모 컴포넌트 사용 예시 -->
<template>
  <BaseCard>
    <template #header>제목</template>
		<!-- 암시적으로 default slot -->
		안녕하세요
		<template #footer>푸터</template>
  </BaseCard>
</template>

4) Dynamic Slot Named

v-slot 디렉티브 전달인자에 데이터를 바인딩하여 동적으로 변경할 수도 있습니다.

<BaseCard>
  <template v-slot:[dynamicSlotName]>
    ...
  </template>

  <!-- with shorthand -->
  <template #[dynamicSlotName]>
    ...
  </template>
</BaseCard>

5) Render Scope

슬롯 콘텐츠는 상위 컴포넌트에 정의되어 있으므로 상위 컴포넌트의 데이터 영역에 접근은 가능하지만 하위 컴포넌트의 영역에는 접근할 수 없습니다.

 

6) Scoped Slots

Render Scope에서 언급했던 것처럼 슬롯 콘텐츠는 자식 컴포넌트의 데이터에 접근할 수 없습니다.

하지만 슬롯 콘텐츠에서 상위 컴포넌트와 하위 컴포넌트 데이터를 모두 사용할 수 있다면 우리는 개발할 때 매우 유용합니다.

이러한 방법으로 우리는 자식 컴포넌트에서 <slot> 요소를 사용할 때 props를 전달하는 것처럼 속성을 슬롯 콘텐츠에 전달할 수 있습니다.

<!-- MyComponent.vue -->
<template>
  <div>
    <slot :text="greetingMessage" :count="count"></slot>
  </div>
</template>
<script>
import { ref } from 'vue';

export default {
  setup() {
    const greetingMessage = ref('Hello World!');
    const count = ref(1);
    return {
      greetingMessage,
      count,
    };
  },
};
</script>

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

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

구조분해할당 문법으로 더 사용하기 편리하게 받을 수 있습니다.

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

7) Named Scoped Slots

이름이 부여된 슬롯도 유사하게 작동합니다. v-slot:name="slotProps”

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

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

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

'개발이 좋아서 > Vue가 좋아서' 카테고리의 다른 글

18장 Template Refs  (0) 2023.09.14
17장 Provide / Inject  (0) 2023.09.14
15장 Non-Prop 속성 (fallthrough 속성)  (0) 2023.09.14
14장 Events  (0) 2023.09.14
13장 Props  (0) 2023.09.14

    티스토리툴바

    단축키

    내 블로그

    내 블로그 - 관리자 홈 전환
    Q
    Q
    새 글 쓰기
    W
    W

    블로그 게시글

    글 수정 (권한 있는 경우)
    E
    E
    댓글 영역으로 이동
    C
    C

    모든 영역

    이 페이지의 URL 복사
    S
    S
    맨 위로 이동
    T
    T
    티스토리 홈 이동
    H
    H
    단축키 안내
    Shift + /
    ⇧ + /

    * 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.