Svelte bind 사용법(input, textarea, select 등)

Svelte의 특징이라고 할 수 있는 bind를 활용해서 값이나 객체를 바인딩을 할 수 있습니다. 어떤 경우에 bind를 사용할 수 있는지 Svelte bind 사용 방법을 알아보겠습니다.

Svelte bind 사용법 개요

스벨트 튜토리얼의 내용을 바탕으로 Svelte의 bind 사용법을 설명해 드리겠습니다. 이 문서에서는 input form 엘리먼트에 바인딩을 적용하는 방법을 알아보도록 합니다.

Input Element

Text Type(bind:value)

다음과 같이 해 주면, input 엘리먼트의 value값에 name 변수가 바인딩됩니다. input 엘리먼트에 type을 지정해 주지 않거나 text로 지정하는 경우 다음과 같이 바인딩할 수 있습니다.

<script>
  let name = '오솔길';
</script>

<input bind:value={name}>

<h1>안녕하세요 {name}님!</h1>
Svelte

그림 1을 보면 초기값 ‘오솔길’이 input의 value에 연결되어 input 상자에도 보이고 해당 값이 h1 태그 안에 보이는 것도 확인할 수 있습니다.

그림 1. svelte bind - input bind:value 사용 초기값 출력
그림 1. svelte bind – input bind:value 사용 초기값 출력

아래 그림 2에서는 input 값을 “나루”로 변경해 보았습니다. 바인딩 된 name 값이 ‘나루’로 변경되고, 해당 값을 출력하는 h1 태그의 내용도 “안녕하세요 나루님!”으로 변경된 것을 확인할 수 있습니다.

그림 2. svelte bind - input bind:value 사용 값 변경시
그림 2. svelte bind – input bind:value 사용 값 변경시

위의 내용은 Bindings / Text inputs 튜토리얼 페이지에서 테스트 해 볼 수 있습니다.

Number 또는 Range Type(bind:value)

input 엘리먼트의 type이 number나 range인 경우에는 숫자값만을 갖도록 바인딩 됩니다.

<script>
  let a = 1;
  let b = 2;
</script>

<label>
  <input type=number bind:value={a} min=0 max=10>
  <input type=range bind:value={a} min=0 max=10>
</label>

<label>
  <input type=number bind:value={b} min=0 max=10>
  <input type=range bind:value={b} min=0 max=10>
</label>

<p>{a} + {b} = {a + b}</p>
Svelte

Bindings / Numeric inputs 페이지에서 테스트 해 보시면 아래의 number를 변경하거나 range를 변경해 줄 때 바인딩된 a와 b 값이 변경되면서, 해당 range나 number의 값과 아래의 p 태그 내의 출력 내용이 함께 변경되는 것을 확인할 수 있습니다.

그림 3. number, range 타입의 input 바인딩

Checkbox Type(bind:checked)

체크박스의 경우에는 bind:checked를 사용하며 변수 yes에는 true나 false의 boolean 값이 들어갑니다.

<script>
  let yes = false;
</script>

<label>
  <input type=checkbox bind:checked={yes}>
  주간 소식지 받기
</label>

{#if yes}
  <p>소식지를 매주 정기적으로 보내드립니다. 다양한 혜택을 누리세요.</p>
{:else}
  <p>이벤트 정보를 받지 못할 거예요.</p>
{/if}

<button disabled={!yes}>구독하기</button>
Svelte

위의 코드의 경우에는 checkbox의 checked가 변경되면 yes 값이 바뀌고, 그 결과 아래의 if문에 나타나는 문장이 변경됩니다. 그리고 button이 yes가 false인 경우 비활성화되고, true인 경우 활성화됩니다. 따라서 체크박스에 표시를 하면 아래와 같이 설명이 변경되고, 구독하기 버튼이 활성화되는 것을 볼 수 있습니다.

그림 4. 체크박스의 bind:checked 사용 결과
그림 4. 체크박스의 bind:checked 사용 결과

Bindings / Checkbox inputs 튜토리얼 페이지에서 코드를 실행해 볼 수 있습니다.

Radio Type(bind:group)

HTML에서는 input 엘리먼트의 type이 radio인 경우 name 값이 같아야 radio가 작동하죠. svelte에서는 bind:group을 이용해서 동일한 변수를 바인딩 해 주면 name을 적어주지 않아도 bind:group 단위로 radio가 작동합니다.

<script>
  let dessert = '딸기';
</script>
<label>
  <input type="radio" value="딸기" bind:group="{dessert}">
  딸기
</label>
<br>
<label>
  <input type="radio" value="바나나" bind:group="{dessert}">
  바나나
</label>
<br>
<p>디저트: {dessert}</p>
Svelte

위의 코드는 아래 그림 5와 같이 작동합니다.

그림 5. 라디오의 bind:group 사용 결과
그림 5. 라디오의 bind:group 사용 결과

위의 내용은 Bindings / Group inputs 튜토리얼 페이지에서 테스트 해 볼 수 있습니다.

Multiple Checkbox(bind:group)

체크박스 여러 개를 하나의 변수에 저장해서 사용하고자 할 때에는 checkbox에 bind:group을 사용하면 됩니다.

<script>
  let flavours = ['민트초코'];
  let menu = [
    '민트초코',
    '딸기',
    '오렌지',
  ];
</script>

{#each menu as flavour}
<label>
  <input type=checkbox bind:group={flavours} name="flavours" value={flavour}>
  {flavour}
</label>
{/each}

선택한 맛: 
{#each flavours as flavour, idx}
  {#if idx > 0}, {/if}{flavour}
{/each}
Svelte

위의 코드는 bind:group을 통해 checkbox가 묶이기 때문에 flavours 변수에 체크된 여러 값이 들어가게 됩니다. 형태는 배열 형태로 들어가며, 아래 그림 6에서 보는 바와 같이 값은 checkbox의 순서대로 값이 들어갑니다.

그림 6. 다중 체크 박스에 bind:group 적용시 사용 결과
그림 6. 다중 체크 박스에 bind:group 적용시 사용 결과

위의 내용은 Bindings / Group inputs 튜토리얼 페이지에서 테스트 해 볼 수 있습니다.

Textarea Element(bind:value)

textarea는 어떻게 해야 할지 고민이 되시나요? Input의 text와 마찬가지로 bind:value 하시면 바인딩할 수 있습니다. 아래의 경우에는 변수명이 value로 동일하죠? 이럴 땐 bind:value={value}라고 적지 않고 bind:value만 적어주시면 됩니다.

<script>
  import { marked } from 'marked';
  let value = `# 마크다운 표기\n글자 표기는 다음과 같이 *이탤릭*, **굵게**`;
</script>

{@html marked(value)}

<textarea bind:value></textarea>

<style>
  textarea { width: 400px; height: 100px; }
</style>
Svelte

아래 그림 7을 보시면 textarea에 작성한 markdown 텍스트가 value에 바인딩 되어 화면에 표시되는 것을 볼 수 있습니다.

그림 7. textarea에 bind:value 적용
그림 7. textarea에 bind:value 적용

위의 내용은 Bindings / Textarea inputs 튜토리얼 페이지에서 테스트 해 볼 수 있습니다.

Select Element(bind:value)

Select 엘리먼트의 바인딩은 bind:value를 사용하면 됩니다. 바인딩 된 값이 비어있으면 첫번째 option의 value를 갖게 됩니다.

<script>
  let selected;
  let questions = [
    {'id': 1, 'text': '가장 존경하는 인물은?'},
    {'id': 2, 'text': '자주 먹는 음식은?'},
    {'id': 3, 'text': '왼손잡이인가요?'},
  ];
</script>

<select bind:value={selected}>
  {#each questions as question}
    <option value={question}>
      {question.text}
    </option>
  {/each}
</select>

<div>
선택한 질문:<br>
{#if selected}
id: {selected.id}<br>
text: {selected.text}
{/if}
</div>
Svelte

위의 코드는 아래 그림 8과 같이 선택하는 질문의 id와 text가 출력되게 해 놓았습니다.

그림 8. Select 엘리먼트에 bind:value 적용
그림 8. Select 엘리먼트에 bind:value 적용

위의 내용은 Bindings / Select bindings 튜토리얼 페이지에서 테스트 해 볼 수 있습니다.

multiple attribute 사용 방법

Select 엘리먼트는 단일선택 뿐 아니라 여러 항목을 선택할 수 있는 multiple attribute을 가질 수 있습니다. 이 경우에는 바인딩되는 변수가 배열로 처리됩니다. 따라서 Line 2와 같이 배열로 처리된다는 점 꼭 기억해 주세요.

<script>
  let selected = [];
  let questions = [
    {'id': 1, 'text': '가장 존경하는 인물은?'},
    {'id': 2, 'text': '자주 먹는 음식은?'},
    {'id': 3, 'text': '왼손잡이인가요?'},
  ];
</script>

<select bind:value={selected} multiple>
  {#each questions as question}
    <option value={question}>
      {question.text}
    </option>
  {/each}
</select>

<div>
선택한 질문:<br>
{#each selected as item}
<div>
id: {item.id} text: {item.text}
</div>
{/each}
</div>
Svelte
그림 9. Select 엘리먼트에 multiple 이용시 bind:value 적용
그림 9. Select 엘리먼트에 multiple 이용시 bind:value 적용

위의 내용은 Bindings / Select multiple bindings 튜토리얼 페이지에서 테스트 해 볼 수 있습니다.

contenteditable attribute(bind:innerHtml, bind:textContent)

contenteditable을 이용한 div 엘리먼트의 속성도 bind:innerHTML이나 bind:textContent를 사용하여 바인딩할 수 있습니다.

<script>
  let html = '<p>여기에 글자를 좀 적어 보세요!</p>';
</script>

<div contenteditable="true" bind:innerHTML={html}></div>
<div contenteditable="true" bind:textContent={html}></div>

<pre>{html}</pre>

<style>
  [contenteditable] {
    width: 400px;
    margin: 5px 0;
    padding: 0.5em;
    border: 1px solid #aaa;
    border-radius: 4px;
  }
</style>
Svelte

그림 10에서 첫번째 div는 bind:innerHTML이 적용되었기 때문에 <p> 태그가 적용되어 보이는 것을 알 수 있으며, 두번째 div는 bind:textContent를 적용했기 때문에 html 태그 자체가 문자열로 보이는 것을 확인할 수 있습니다.

그림 10. contenteditable 속성 사용시 bind:innerHtml, bind:textContent 적용
그림 10. contenteditable 속성 사용시 bind:innerHtml, bind:textContent 적용

위의 내용은 Bindings / contenteditable bindings 튜토리얼 페이지에서 테스트 해 볼 수 있습니다.

each block 바인딩

아래에서는 each문을 활용하여 todos 배열의 객체 내의 값과 연결지어서 처리하는 모습을 볼 수 있습니다.

<script>
  let todos = [
    {done: false, text: 'svelte 튜토리얼 끝내기'},
    {done: false, text: '500억 벌기'},
    {done: false, text: '앱 개발하기'},
  ];
</script>

{#each todos as todo}
<label>
<input type="checkbox" bind:checked={todo.done}>
{todo.text}
</label>
{/each}
Svelte

이제 체크박스를 클릭하여 선택하면 todos 배열의 각 done 항목 값이 true로 바뀌게 된다.

그림 11. each 블록 내에서 bind:checked 적용
그림 11. each 블록 내에서 bind:checked 적용

위의 내용은 Bindings / Each block bindings 튜토리얼 페이지에서 테스트 해 볼 수 있습니다.

관련 자료

Svelte 문서의 Element directives를 확인하시면 도움이 될 것입니다.

같이 읽으면 좋은 글

Leave a Comment