본문 바로가기
프로그래밍/Web

svelte 번역 - 8 - Template Syntax / Special elements

by 사악신 2024. 10. 17.

<slot>

Svelte에서 컴포넌트는 <slot> 태그를 사용하여 자식 콘텐츠를 받을 수 있습니다. 이 콘텐츠는 기본적으로 컴포넌트 소비자가 제공한 자식 요소들로 대체됩니다. 자식 요소가 없을 경우, 슬롯 안에 있는 대체 콘텐츠(fallback content)가 렌더링됩니다.

기본 사용법:

<!-- Widget.svelte -->
<div>
  <slot>이 기본 콘텐츠는 자식 요소가 제공되지 않으면 렌더링됩니다.</slot>
</div>

<!-- App.svelte -->
<Widget />
<!-- 이 컴포넌트는 기본 슬롯 콘텐츠를 렌더링합니다. -->

<Widget>
  <p>이 자식 콘텐츠는 기본 슬롯 콘텐츠를 덮어씁니다.</p>
</Widget>

명명된 슬롯(Named Slots):

슬롯에 이름을 지정하여 특정 위치에 콘텐츠를 전달할 수 있습니다. 각 명명된 슬롯은 대체 콘텐츠를 가질 수 있습니다.

<!-- Widget.svelte -->
<div>
  <slot name="header">헤더가 제공되지 않았습니다.</slot>
  <p>헤더와 푸터 사이의 콘텐츠</p>
  <slot name="footer">푸터가 제공되지 않았습니다.</slot>
</div>

<!-- App.svelte -->
<Widget>
  <h1 slot="header">Hello</h1>
  <p slot="footer">© 2019 Svelte Industries</p>
</Widget>

명명된 슬롯에 컴포넌트를 전달하려면 slot="name" 속성을 사용하면 됩니다. 래퍼 요소 없이 콘텐츠를 전달하려면 <svelte:fragment>를 사용할 수 있습니다.

<!-- App.svelte -->
<Widget>
  <HeaderComponent slot="header" />
  <svelte:fragment slot="footer">
    <p>All rights reserved.</p>
    <p>Copyright (c) 2019 Svelte Industries</p>
  </svelte:fragment>
</Widget>

$$slots

$$slots는 부모 컴포넌트에서 전달된 슬롯의 이름을 키로 하는 객체입니다. 특정 슬롯이 제공되지 않았다면, 해당 이름은 $$slots 객체에 존재하지 않습니다. 이를 통해 컴포넌트는 슬롯을 렌더링할지 여부를 결정할 수 있습니다.

<!-- Card.svelte -->
<div>
  <slot name="title"></slot>
  {#if $$slots.description}
    <hr />
    <slot name="description"></slot>
  {/if}
</div>

<!-- App.svelte -->
<Card>
  <h1 slot="title">블로그 포스트 제목</h1>
  <!-- "description" 슬롯이 없으므로 렌더링되지 않음 -->
</Card>

슬롯에 값을 전달하기 (<slot prop={value}>)

슬롯은 값(속성)을 전달할 수 있으며, 부모는 let: 지시어를 사용해 이 값을 슬롯 템플릿에서 접근할 수 있습니다.

<!-- FancyList.svelte -->
<ul>
  {#each items as item}
    <li class="fancy">
      <slot prop={item}></slot>
    </li>
  {/each}
</ul>

<!-- App.svelte -->
<FancyList {items} let:prop={thing}>
  <div>{thing.text}</div>
</FancyList>

명명된 슬롯도 값을 전달할 수 있습니다.

<!-- FancyList.svelte -->
<ul>
  {#each items as item}
    <li class="fancy">
      <slot name="item" {item}></slot>
    </li>
  {/each}
</ul>

<!-- App.svelte -->
<FancyList {items}>
  <div slot="item" let:item>{item.text}</div>
  <p slot="footer">© 2019 Svelte Industries</p>
</FancyList>

<svelte:self>

<svelte:self> 태그는 컴포넌트 자체를 재귀적으로 포함할 때 사용됩니다. 무한 루프를 방지하기 위해 반드시 if 또는 each 블록 안에 있어야 합니다.

<!-- App.svelte -->
<script lang="ts">
  export let count: number;
</script>

{#if count > 0}
  <p>카운트 다운... {count}</p>
  <svelte:self count={count - 1} />
{:else}
  <p>발사!</p>
{/if}

<svelte:component>

<svelte:component> 태그는 동적으로 컴포넌트를 렌더링할 수 있게 해줍니다. this 속성에 컴포넌트 생성자를 전달하여 렌더링할 컴포넌트를 동적으로 지정할 수 있습니다. this 속성이 falsy이면, 컴포넌트가 렌더링되지 않습니다.

<svelte:component this={currentComponent} prop={value} />

<svelte:element>

<svelte:element>는 동적으로 요소의 종류를 지정하여 렌더링할 수 있습니다. 이는 CMS에서 가져온 리치 텍스트 콘텐츠를 표시할 때 유용합니다. 속성 및 이벤트 리스너를 해당 요소에 적용할 수 있습니다.

<script>
  let tag = 'div';
  export let handler;
</script>

<svelte:element this={tag} on:click={handler}>Foo</svelte:element>

<svelte:window>

<svelte:window> 태그는 window 객체에 이벤트 리스너를 추가하고, 컴포넌트가 파괴될 때 자동으로 제거합니다. 또한, scrollX, scrollY 등 여러 속성에 바인딩할 수 있습니다.

<svelte:window on:keydown={handleKeydown} />
<svelte:window bind:scrollY={scrollY} />

<svelte:document> / <svelte:body> / <svelte:head>

  • <svelte:document>document 객체에 이벤트 리스너를 추가합니다. 예를 들어 visibilitychange와 같은 이벤트는 window가 아닌 document에서 발생합니다.
  • <svelte:body>document.body에 이벤트 리스너를 추가하는데 유용합니다.
  • <svelte:head>는 문서의 <head> 섹션에 요소를 삽입할 수 있습니다.
<svelte:document on:visibilitychange={handleVisibilityChange} />
<svelte:body on:mouseenter={handleMouseenter} />
<svelte:head>
  <title>페이지 제목</title>
  <meta name="description" content="SEO 설명입니다." />
</svelte:head>

<svelte:options>

<svelte:options> 태그는 컴포넌트별 컴파일러 옵션을 지정하는 데 사용됩니다. 예를 들어, 컴포넌트를 커스텀 엘리먼트로 컴파일할 때 유용합니다.

<svelte:options customElement="my-custom-element" />

가능한 옵션은 다음과 같습니다:

  • immutable: 불변성을 사용하는 경우, 변경 여부를 간단한 참조 비교로 판단하도록 설정
  • accessors: 컴포넌트의 props에 대해 getter와 setter를 추가
  • namespace: 네임스페이스를 지정 (예: "svg")

<svelte:fragment>

<svelte:fragment> 태그는 래퍼 요소 없이 명명된 슬롯에 콘텐츠를 전달할 수 있게 해줍니다. 이를 통해 문서의 레이아웃을 그대로 유지하면서 콘텐츠를 전달할 수 있습니다.

<Widget>
  <h1 slot="header">Hello</h1>
  <svelte:fragment slot="footer">
    <p>All rights reserved.</p>
    <p>Copyright (c) 2019 Svelte Industries</p>
  </svelte:fragment>
</Widget>

Svelte에서 슬롯, 동적 컴포넌트, 그리고 다양한 DOM 요소와의 상호작용을 통해 컴포넌트를 더욱 유연하고 강력하게 구성할 수 있습니다.

반응형

댓글