Svelte에서 데이터 흐름이 보통 Top-Down으로 부모 컴포넌트가 자식 컴포넌트에게 props로 데이터를 넘겨주는 방식인데, bind
를 통해 다른 데이터 흐름을 구현할 수 있습니다.
// App.svelte
...
<input value={name} />
<h1>Hello {name}!</h1>
<input bind:value={name} />
이렇게 name을 input의 value에 bind하면 name이 변할 때 input의 내용이 변하고, input의 내용이 변하면 name이 변하게 됩니다.(App <-> input)DOM에서 모든 것은 String이라서 숫자를 다룰 때 불편합니다.
하지만 type=number
, type=range
input일 때 bind:value를 사용하면 Svelte가 value가 숫자라는 것을 신경써줍니다.
...
<input type=number bind:value={a} min=0 max=10/>
<input type=range bind:value={a} min=0 max=10/>
<p>{a} + {a} = {a+a}</p>
Svelte에서 Checkbox는 value 대신 checked를 bind합니다.
<input type=checkbox bind:checked={yes}/>
여러 개의 input을 같은 value로 공유하고 싶다면, bind:group
으로 하나의 값을 공유할 수 있습니다.
let scoop = 1
...
<label>
<input type=radio bind:group={scoop} name="scoop" value=1>
"한 스푼"
</label>
...
<textarea>
엘리먼트에서도 text input과 비슷하게 사용할 수 있습니다.
...
<textarea bind:value={value}></textarea>
<textarea bind:value>
로 축약할 수 있습니다.<select>
엘리먼트에서 bind:value
를 통해 무엇이 선택되었는지 알 수 있다.
let selected
let questions = [ {id: 1, text: "문제1. ..."}, ...]
...
<select bind:value={selected} on:change={() => answer = ''}>
{#each questions as question}
<option value={question}>{question.text}</option>
{/each}
</select>
questions
를 each
block으로 option
을 만들고 선택된 질문 객체가 selected에 담깁니다.selected
는 undefined
이므로 조심해서 사용해야 합니다.<select>
에서 여러 개를 선택하고싶을 경우 <select multiple>
을 사용할 수 있습니다.
<select multiple bind:value={flavours}>
{#each menu as flavour}
<option value={flavour}>
{flavour}
</option>
{/each}
</select>
flavour
들이 배열로 flavours
에 담깁니다.contenteditalbe=true
속성을 통해 다음과 같은 것을 binding할 수 있습니다.
<div
contenteditable=true
bind:innerHTML={html}
></div>
bind
하고 제어할 수 있습니다.each
block 안의 요소도 bind
할 수 있습니다.
{#each todos as todo}
<input type=checkbox bind:checked={todo.done}/>
...
{/each}
bind
대신 이벤트 핸들러를 사용하면 됩니다.<audio>
, <video>
element는 bind
할 수 있는 여러 속성이 있습니다.
6가지의 readonly binding
이 있고
read-write binding
이 있다.<video>
에는 2가지의 readonly binding
이 더 있습니다.모든 block-level의 엘리먼트는 자신의 길이/높이값을 갖는 clientWidth, clientHeight, offsetWidth, offsetHeight가 있고 이를 bind할 수 있습니다.
...
<p>size: {w}px x {h}px</p>
<div bind:clientWidth={w} bind:clientHeight={h}>
<span style="font-size: {size}px">{text}</span>
</div>
div
의 길이,높이 값이 담깁니다.모든 엘리먼트와 컴포넌트는 this
를 bind
할 수 있습니다.
this를 통해 해당 엘리먼트를 조작할 수 있습니다.
DOM 엘리먼트 뿐 아니라 컴포넌트도 bind할 수 있습니다.
<h1 style="color: {pin ? '#333' : '#ccc'}">{view}</h1>
<Keypad bind:value={pin} on:submit={handleSubmit}/>
DOM 엘리먼트를 bind할 수 있듯이 컴포넌트 인스턴스를 바인드할 수 있습니다.
// App.svelte
...
<InputField bind:this={field} />
<button on:click={() => field.focus()}>
버튼
</button>
// InputField.svelte
export function focus() {
input.focus();
}
</script>
<input bind:this={input} />
<InputField>
의 인스턴스를 field에 binding 했습니다.field
를 사용해서 이 컴포넌트와 상호작용할 수 있습니다.