이번에는 Svelte의 일반 this 요소 바인딩에 대해 이해해보자 아래의 코드는 Edit 버튼을 클릭했을 때, input 요소에 자동으로 focus 처리 동작을 하도록 만들어진 코드이다.
App.svelte
<script>
let isShow = false;
function toggle() {
isShow = !isShow;
const inputEl = document.querySelector("input");
inputEl && inputEl.focus();
}
</script>
<button on:click={toggle}>Edit!</button>
{#if isShow}
<input />
{/if}
하지만 해당 코드는 자동으로 focus 처리가 되지 않는다. (아래 이미지 보면 마우스로 클릭해서 focus 처리함)
왜 focus가 되지 않을까? 이것은 데이터가 갱신되었을 때 바로 화면이 바뀌지 않기 때문이다. 데이터가 갱신되고 다음 로직이 처리되기 전에 화면이 갱신되도록 기다려야지만 화면이 바뀐다.
import { tick } from "svelte";
let isShow = false;
async function toggle() {
isShow = !isShow;
await tick();
const inputEl = document.querySelector("input");
inputEl && inputEl.focus();
}
따라서 tick을 적용하면 아래와 같이 자동으로 focus 처리가 수행되는 것을 확인할 수 있다.
이는 이미 배워서 아는 사실이다. 이 밖에 스벨트에서는 const inputEl = document.querySelector("input");
와 같이 직접 돔을 검색하는 방법 이외에도 일반요소에 바인딩 할 수 있도록 하는 this를 제공한다.
<script>
import { tick } from "svelte";
let isShow = false;
let inputEl;
async function toggle() {
isShow = !isShow;
await tick();
inputEl && inputEl.focus();
}
</script>
<button on:click={toggle}>Edit!</button>
{#if isShow}
<input bind:this={inputEl} />
{/if}
위와 같이 input
에 bind
요소로 this
를 주입해주면 별도의 요소를 검색하지 않고 input
요소를 참조하도록 만들어줄 수 있다. 이는 전체 돔을 검색하는 성능을 줄일 수 있도록 해주므로 직접 요소를 바인딩 하는 방법으로 성능을 최적화해주는 것이 바람직하다.
Svelte의 여러가지 입력 요소 바인딩 패턴에 대해 알아보자
let text = "";
let number = 3;
let checked = false;
let fruits = ["Apple", "Banana", "Cherry"];
let selectedFruits = [];
let group = "Banana";
let textarea = "";
let select = "";
let multipleSelect = ["Banana", "Cherry"];
위와 같은 변수가 있다고 했을 때 기본적인 input은 아래와 같은 이벤트 바인딩을 가질 수 있다.
<!-- let text = ''; -->
<section>
<h2>Text</h2>
<input type="text" bind:value={text} />
</section>
input 요소는 양방향 데이터 바인딩을 한다. range input의 경우에도 동일하게 연결할 수 있다.
<!-- let number = 3 -->
<section>
<h2>Number/Range</h2>
<div>
<input type="number" bind:value={number} min="0" max="10" />
</div>
<div>
<input type="range" bind:value={number} min="0" max="10" />
</div>
</section>