[Svelte Tutorial]6. Bindings

이진규·2023년 5월 3일
0

Svelte Tutorial

목록 보기
6/7
post-thumbnail

6. Bindings

Svelte에서 데이터 흐름이 보통 Top-Down으로 부모 컴포넌트가 자식 컴포넌트에게 props로 데이터를 넘겨주는 방식인데, bind를 통해 다른 데이터 흐름을 구현할 수 있습니다.

6-1. Text inputs

// App.svelte
...
<input value={name} />
<h1>Hello {name}!</h1>
  1. 이런 코드에서 name의 변화에 따라 input의 내용이 변하게 됩니다. (App -> input)
  2. 하지만 input의 변화에 따라 name이 변하지는 않습니다.(App <x- input)
  3. <input bind:value={name} /> 이렇게 name을 input의 value에 bind하면 name이 변할 때 input의 내용이 변하고, input의 내용이 변하면 name이 변하게 됩니다.(App <-> input)

6-2. Numeric inputs

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>

6-3. Checkbox inputs

Svelte에서 Checkbox는 value 대신 checked를 bind합니다.

<input type=checkbox bind:checked={yes}/>

6-4. Group inputs

여러 개의 input을 같은 value로 공유하고 싶다면, bind:group으로 하나의 값을 공유할 수 있습니다.

let scoop = 1
...
<label>
  <input type=radio bind:group={scoop} name="scoop" value=1>
  "한 스푼"
</label>
...
  1. 이런 input이 여러개가 있다고 할 때, 선택된 input의 value에 따라 scoop이 변하게 됩니다.

6-5. Textarea inputs

<textarea> 엘리먼트에서도 text input과 비슷하게 사용할 수 있습니다.

...
<textarea bind:value={value}></textarea>
  1. textarea의 내용이 변경되면 value가 변경되고 value가 변경되면 textarea의 내용이 변경됩니다.
  2. 위의 예시처럼 속성과 변수의 이름이 같은 경우 <textarea bind:value>로 축약할 수 있습니다.

6-6. Select bindings

<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>
  1. select element 안에 질문들이 담겨있는 questionseach block으로 option을 만들고 선택된 질문 객체가 selected에 담깁니다.
  2. 처음에 아무것도 선택된 것이 없을 때 selectedundefined이므로 조심해서 사용해야 합니다.

6-7. Select multiple

<select>에서 여러 개를 선택하고싶을 경우 <select multiple>을 사용할 수 있습니다.

<select multiple bind:value={flavours}>
  {#each menu as flavour}
    <option value={flavour}>
      {flavour}
    </option>
  {/each}
</select>
  1. 선택된 flavour들이 배열로 flavours에 담깁니다.
  2. 드래그나 컨트롤/커맨드 키를 통해 여러 개를 선택할 수 있습니다.

6-8. Contenteditable bindings

contenteditalbe=true속성을 통해 다음과 같은 것을 binding할 수 있습니다.

  • innerHTML
  • innrText
  • textContent
<div
  contenteditable=true
  bind:innerHTML={html}
></div>
  1. 이 속성에 true값을 주면 value 대신 직접 HTML을 bind하고 제어할 수 있습니다.

6-9. Each block bindings

each block 안의 요소도 bind할 수 있습니다.

{#each todos as todo}
  <input type=checkbox bind:checked={todo.done}/>
    ...
{/each}
  1. 이런식으로 bind할 경우, todos 배열을 변화시킬 수 있습니다. 즉 원본 배열을 변경시킬 우려가 있기 때문에, 그러기 싫다면 bind 대신 이벤트 핸들러를 사용하면 됩니다.

6-10. Media elements

<audio>, <video> element는 bind할 수 있는 여러 속성이 있습니다.
6가지의 readonly binding이 있고

  • duration: 영상의 전체 길이(초 단위)
  • buffered: {start, end} 객체가 담긴 배열
  • seekable: {start, end} 객체가 담긴 배열
  • played: {start, end} 객체가 담긴 배열
  • seeking: boolean == 재생중인지?
  • ended: boolean == 끝났는지?
    5가지의 read-write binding이 있다.
  • currentTime: 재생중인 비디오의 현재시간
  • playbackRate: 재생속도. 1이 기본속도
  • paused: 정지
  • volume: 0-1사이의 값으로 나타낸 볼륨
  • muted: 소리가 무음인지에 대한 boolean값
    <video>에는 2가지의 readonly binding이 더 있습니다.
  • videoWidth: 비디오 화면의 길이
  • videoHeight: 비디오 화면의 높이

6-11. Dimensions

모든 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>
  1. w,h에 div의 길이,높이 값이 담깁니다.

6-12. This

모든 엘리먼트와 컴포넌트는 thisbind할 수 있습니다.
this를 통해 해당 엘리먼트를 조작할 수 있습니다.

6-13. Component bindings

DOM 엘리먼트 뿐 아니라 컴포넌트도 bind할 수 있습니다.

<h1 style="color: {pin ? '#333' : '#ccc'}">{view}</h1>
<Keypad bind:value={pin} on:submit={handleSubmit}/>
  1. 키패드에 아무것도 입력되지 않았다면, 회색으로 보여주고 입력되었을 때 검은색으로 보여줍니다.
  2. 데이터 흐름이 너무 많을 때 추적이 어려울 수 있기 때문에, 컴포넌트 바인딩은 조심해서 사용해야 합니다.

6-14. Binding to component instances

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} />
  1. App의 <InputField>의 인스턴스를 field에 binding 했습니다.
  2. field를 사용해서 이 컴포넌트와 상호작용할 수 있습니다.

튜토리얼 6장 끝

참고문헌

Svelte Tutorial 6장 Bindings

profile
개발자

0개의 댓글