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 태그 안에 보이는 것도 확인할 수 있습니다.
아래 그림 2에서는 input 값을 “나루”로 변경해 보았습니다. 바인딩 된 name 값이 ‘나루’로 변경되고, 해당 값을 출력하는 h1 태그의 내용도 “안녕하세요 나루님!”으로 변경된 것을 확인할 수 있습니다.
위의 내용은 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>
SvelteBindings / Numeric inputs 페이지에서 테스트 해 보시면 아래의 number를 변경하거나 range를 변경해 줄 때 바인딩된 a와 b 값이 변경되면서, 해당 range나 number의 값과 아래의 p 태그 내의 출력 내용이 함께 변경되는 것을 확인할 수 있습니다.
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인 경우 활성화됩니다. 따라서 체크박스에 표시를 하면 아래와 같이 설명이 변경되고, 구독하기 버튼이 활성화되는 것을 볼 수 있습니다.
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와 같이 작동합니다.
위의 내용은 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의 순서대로 값이 들어갑니다.
위의 내용은 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에 바인딩 되어 화면에 표시되는 것을 볼 수 있습니다.
위의 내용은 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가 출력되게 해 놓았습니다.
위의 내용은 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위의 내용은 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 태그 자체가 문자열로 보이는 것을 확인할 수 있습니다.
위의 내용은 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로 바뀌게 된다.
위의 내용은 Bindings / Each block bindings 튜토리얼 페이지에서 테스트 해 볼 수 있습니다.
관련 자료
Svelte 문서의 Element directives를 확인하시면 도움이 될 것입니다.