bind: 디렉티브 — 양방향 바인딩
bind: 디렉티브 — 양방향 바인딩
데이터는 보통 부모에서 자식으로 흐르지만, bind: 디렉티브는 데이터가 자식에서 부모로 흐르는 방향을 가능하게 해줘요. 일반 문법은 bind:property={expression} 이고, expression은 변수나 객체 속성 같은 lvalue여야 해요. 표현식이 속성과 같은 이름의 식별자라면 생략할 수 있어요.
<input bind:value={value} />
<!-- 위와 아래는 같습니다 -->
<input bind:value />
Svelte는 바인딩된 값을 갱신하는 이벤트 리스너를 만들어요. 요소가 같은 이벤트의 리스너를 이미 갖고 있으면, 그 리스너가 바운드 값이 갱신되기 전에 실행돼요. 대부분의 바인딩은 양방향(two-way) 이라서 값을 바꾸면 요소에도 반영되고 그 반대도 돼요. 일부 바인딩은 읽기 전용(readonly) 이라 값을 바꿔도 요소에는 영향이 없어요.
함수 바인딩(Function bindings)
bind:property={get, set}처럼 get과 set 함수를 쓸 수도 있어요. 이를 통해 검증과 변환을 수행할 수 있어요.
<input bind:value={ () => value, (v) => value = v.toLowerCase()} />
clientWidth 같은 읽기 전용 바인딩에서는 get 값이 null이어야 해요. 함수 바인딩은 Svelte 5.9.0부터 쓸 수 있어요.
<input> 요소의 bind:value 디렉티브는 input의 value 속성을 바인딩해요. type="number"나 type="range" 같은 숫자 input의 경우 값이 숫자로 변환돼요.
bind:group은 같은 Svelte 컴포넌트 안의 input에서만 동작해요.
<details> 요소는 open 속성을 바인딩할 수 있어요.
<details bind:open={isOpen}>
<summary>How do you comfort a JavaScript bug?</summary>
<p>You console it.</p>
</details>
bind:this
DOM 노드에 대한 참조를 얻으려면 bind:this를 사용해요. 값은 컴포넌트가 마운트될 때까지 undefined이므로, 컴포넌트 초기화 중이 아니라 이펙트나 이벤트 핸들러 안에서 읽어야 해요.
<script>
/** @type {HTMLCanvasElement} */
let canvas;
$effect(() => {
const ctx = canvas.getContext('2d');
drawStuff(ctx);
});
</script>
<canvas bind:this={canvas}></canvas>
컴포넌트도 bind:this를 지원해서, 컴포넌트 인스턴스를 프로그래밍 방식으로 상호작용할 수 있게 해줘요.
컴포넌트 props 바인딩
bind:property={variable} 문법으로 요소처럼 컴포넌트 props에도 바인딩할 수 있어요.
<Keypad bind:value={pin} />
Svelte props는 바인딩 없이도 반응형이지만, 그 반응성은 기본적으로 컴포넌트 안으로 아래 방향으로만 흐르기만 해요. bind:property를 쓰면 컴포넌트 안의 속성 변경이 컴포넌트 밖으로 흘러 올라올 수 있어요. 속성을 bindable로 표시하려면 $bindable 런을 써야 해요. bindable 속성은 fallback 값을 가질 수 있어요.
더 알아보기
- 바인딩 가능한 props
$bindable: https://svelte.dev/docs/svelte/$bindable - What are runes?: https://svelte.dev/docs/svelte/what-are-runes
- Template syntax: https://svelte.dev/docs/svelte/template-syntax