이번 포스팅에서는 Svelte에서 이벤트를 처리하는 방법에 대해 정리해 보았다. 특히 dispatch
를 눈여겨 보자!
스벨트는 DOM 이벤트를 처리할 때 이벤트 수식어 기능을 제공한다.
<script>
function handleClick() {
alert('no more alert');
}
</script>
<button on:click|once={handleClick}>Click me!</button>
위는 once 이벤트 수식어를 사용한 코드이다. once 이벤트 수식어는 이벤트가 발생했을 때 이벤트 핸들러를 단 한 번만 호출한다.
preventDefault
태그의 기본 동작을 막는 이벤트 수식어
stopPropagation
이벤트가 다음 요소로 흐르는 것을 막는 이벤트 수식어
passive
터치 혹은 휠 이벤트로 발생하는 스크롤의 성능을 향상시키는 이벤트 수식어
-> 스벨트는 안전한 곳에 자동으로 추가한다!nonpassive
passive: false
를 지정해 주는 수식어capture
캡처 방식으로 이벤트 핸들러를 실행함
once
이벤트 핸들러를 단 한번만 실행하도록 하는 이벤트 수식어
self
event.target
과 이벤트 핸들러를 정의한 요소가 같을 때 이벤트 핸들러를 실행하도록 하는 이벤트 수식어
on:click|once|capture={...}
위 코드처럼 체인으로 연결해 수식어 여러 개를 사용할 수도 있다.
컴포넌트에서 이벤트를 발생시켜 상위 컴포넌트로 데이터를 전달할 수 있다.
dispatch: ((name: string, detail?: any) => void) = createEventDispatcher();
createEventDispatcher 함수는 이벤트를 발생시키는 dispatch 함수를 반환한다. dispatch 함수는 name
과 detail
두 개의 파라미터를 전달받는다.
name
이벤트 이름
detail
이벤트 객체의 detail 필드에 담을 데이터
여기서 주의할 점은 createEventDispatcher()는 컴포넌트가 처음 생성될 때 호출되어야 한다. 함수 안에서 createEventDispatcher()를 호출하여 dispatch를 사용하면 이벤트 전달이 되지 않는다. 아래에서 코드와 함께 dispatch 사용법을 연습해 보자!
<!-- src/Inner.svelte -->
<script>
import { createEventDispatcher } from "svelte";
const dispatch = createEventDispatcher();
function sayHello() {
dispatch('message', {
text: '안녕!'
})
}
</script>
<button on:click={sayHello}>인사하기</button>
<script>
import Inner from "./Inner.svelte";
function handleMessage(event) {
debugger;
alert(event.detail.text);
}
</script>
<Inner on:message={handleMessage} />
디버깅을 해 보면 event.detail에 하위 컴포넌트에서 전달한 text라는 데이터를 확인할 수 있다. 이처럼 하위에서 상위로 데이터를 보낼 일이 있을 때 사용하면 아주 편리하다. 😎
CreateEventDispatcher로 생성된 컴포넌트 이벤트는 CustomEvent를 말한다. 개발자가 직접 정의하여 사용할 수 있는 이벤트다.
DOM 이벤트와 달리 컴포넌트 이벤트는 버블링되지 않는다. 자동으로 상위 요소로 이벤트가 전달되지 않기 때문에 의도적으로 부모 컴포넌트로 이벤트를 전달해야 한다.
<!-- src/Inner.svelte -->
<script>
import { createEventDispatcher } from "svelte";
const dispatch = createEventDispatcher();
function sayHello() {
dispatch('message', {
text: '안녕!'
})
}
</script>
<button on:click={sayHello}>인사하기</button>
<!-- src/Outer.svelte -->
<script>
import Inner from "./Inner.svelte";
import { createEventDispatcher } from "svelte";
const dispatch = createEventDispatcher();
function forward(event) {
dispatch('message', event.detail);
}
</script>
<Inner on:message={forward}/>
<script>
import Outer from "./Outer.svelte";
function handleMessage(event) {
alert(event.detail.text);
}
</script>
<Outer on:message={handleMessage} />
스벨트에서는 약어를 제공하기 때문에 Outer.svelte의 코드를 좀 더 간결하게 작성할 수도 있다.
<!-- src/Outer.svelte -->
<script>
import Inner from "./Inner.svelte";
</script>
<Inner on:message/>