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

svelte 번역 - 2 - Template Syntax / Svelte Components

by 사악신 2024. 10. 17.

Svelte Components

Svelte 컴포넌트는 Svelte 애플리케이션의 기본 구성 요소입니다. 이들은 .svelte 파일에 작성되며, HTML의 상위 집합을 사용합니다.

세 가지 섹션(스크립트, 스타일, 마크업)은 모두 선택 사항입니다.

<script>
  // 로직은 여기에 작성됩니다.
</script>

<!-- 마크업 (0개 이상의 항목) -->

<style>
  /* 스타일은 여기에 작성됩니다. */
</style>

<script> 섹션

<script> 블록에는 컴포넌트 인스턴스가 생성될 때 실행되는 JavaScript가 포함됩니다. 최상위 레벨에서 선언된 변수는 컴포넌트의 마크업에서 '보이는' 상태입니다. 여기에 추가적인 규칙 네 가지가 있습니다.

1. export는 컴포넌트 속성을 만듭니다.

Svelte는 export 키워드를 사용하여 변수 선언을 속성(prop)으로 지정합니다. 이렇게 지정된 변수는 컴포넌트의 소비자(다른 컴포넌트)에서 접근할 수 있습니다.

<script>
  export let foo;

  // 속성으로 전달된 값은 즉시 사용할 수 있습니다.
  console.log({ foo });
</script>

속성에 대해 기본 초기값을 지정할 수 있으며, 이는 컴포넌트가 인스턴스화될 때 소비자가 속성을 지정하지 않으면 사용됩니다. 속성이 이후에 업데이트되면 지정되지 않은 속성은 undefined로 설정됩니다.

<script>
  export let bar = 'optional default initial value';
  export let baz = undefined;
</script>

const, class, functionexport하는 경우, 외부에서 읽기 전용으로만 사용할 수 있습니다. 함수는 유효한 속성 값으로 사용할 수 있습니다.

<script lang="ts">
  // 읽기 전용
  export const thisIs = 'readonly';

  export function greet(name: string) {
    alert(`hello ${name}!`);
  }

  // 속성으로 사용
  export let format = (n) => n.toFixed(2);
</script>

속성을 읽기 전용으로 만든 경우, bind:this 문법을 사용하여 엘리먼트의 속성으로 접근할 수 있습니다.

2. 할당은 '반응적'입니다.

컴포넌트 상태를 변경하고 다시 렌더링하려면 로컬로 선언된 변수에 값을 할당하면 됩니다.

<script>
  let count = 0;

  function handleClick() {
    // count 변수가 마크업에서 참조되면 업데이트가 발생합니다.
    count = count + 1;
  }
</script>

Svelte의 반응성은 할당을 기반으로 하므로, .push().splice() 같은 배열 메서드는 자동으로 업데이트를 트리거하지 않습니다. 할당이 필요합니다.

<script>
  let arr = [0, 1];

  function handleClick() {
    arr.push(2);
    arr = arr;
  }
</script>

3. $:는 문을 반응적으로 만듭니다.

최상위 문장에 $:를 붙이면 해당 문이 반응적으로 실행됩니다. 이 문장은 다른 스크립트 코드가 실행된 후, 그리고 컴포넌트 마크업이 렌더링되기 전에 실행됩니다.

<script>
  export let title;
  export let person;

  $: document.title = title;

  $: {
    console.log(`여러 문장을 결합할 수 있습니다.`);
    console.log(`현재 제목은 ${title}입니다.`);
  }

  $: ({ name } = person);
</script>

4. 스토어는 $로 접근

Svelte에서 스토어는 반응적으로 값에 접근할 수 있도록 하는 객체입니다. svelte/store 모듈에는 최소한의 스토어 구현이 포함되어 있습니다.

스토어 참조가 있을 때는 $를 붙여서 값에 접근할 수 있습니다. 스토어 값이 변경되면 자동으로 구독하고, 적절한 시점에 구독을 해지합니다.

<script>
  import { writable } from 'svelte/store';

  const count = writable(0);
  console.log($count); // 0 출력

  count.set(1);
  console.log($count); // 1 출력

  $count = 2;
  console.log($count); // 2 출력
</script>

<style> 블록

Svelte의 <style> 블록은 해당 컴포넌트에만 적용되는 CSS 스타일을 정의하는 곳입니다. 이 스타일은 자동으로 해시가 붙은 클래스를 통해 적용되며, 클래스는 해당 컴포넌트에만 한정됩니다.

<style>
  p {
    /* 이 스타일은 해당 컴포넌트의 <p> 요소에만 적용됩니다 */
    color: burlywood;
  }
</style>

전역 선택자에 스타일을 적용하려면 :global(...) 문법을 사용합니다.

<style>
  :global(body) {
    /* 이 스타일은 <body> 전체에 적용됩니다 */
    margin: 0;
  }

  div :global(strong) {
    /* 이 스타일은 이 컴포넌트의 <div> 내부에 있는 모든 <strong> 요소에 적용됩니다 */
    color: goldenrod;
  }

  p:global(.red) {
    /* 이 스타일은 이 컴포넌트의 클래스가 'red'인 모든 <p> 요소에 적용됩니다 */
  }
</style>

@keyframes를 전역에서 접근할 수 있도록 하려면, 애니메이션 이름에 -global-을 접두사로 붙여야 합니다. 이렇게 지정한 애니메이션 이름은 컴파일된 후에도 그대로 사용됩니다.

<style>
  @keyframes -global-my-animation-name {
    /* 애니메이션 코드는 여기에 작성됩니다 */
  }
</style>

Svelte 컴포넌트는 하나의 최상위 <style> 태그를 가질 수 있지만, 다른 요소나 논리 블록 내부에 중첩된 <style> 태그도 가질 수 있습니다. 그러나 이 경우, 해당 스타일은 그대로 DOM에 삽입되며, Svelte에서 처리되거나 범위가 설정되지 않습니다.

<div>
  <style>
    /* 이 스타일 태그는 그대로 DOM에 삽입됩니다 */
    div {
      color: red;
    }
  </style>
</div>

이렇게 작성된 스타일은 일반적으로 전역 스타일과 비슷하게 동작합니다.

반응형

댓글