Svelte에서 이벤트 처리 방법
Svelte에서는 on 지시자를 사용하여 DOM 이벤트 또는 사용자 정의 이벤트를 처리할 수 있습니다. 예를 들어, button 태그에서 click 이벤트가 발생하거나 textarea 태그에서 change 이벤트가 발생하는 경우 이벤트를 처리하기 위한 로직을 구현할 수 있습니다.
다음 예제는 버튼을 클릭하면, 콘솔에 "Hello"를 출력합니다.
[App.svelte]
<div>
<button on:click={(e) => console.log('Hello')}>
Hello 출력
</button>
</div>
<style>
div {
text-align: center;
}
</style>
이벤트를 처리하는 로직은 위 예제처럼 HTML 영역에서 익명 함수로 구현하거나 아래 예제처럼 이벤트를 처리하는 함수를 script 영역에 구현 후 이벤트 핸들러에 함수를 전달합니다.
<script>
function handleButtonClick(e) {
console.log('Hello')
}
</script>
<div>
<button on:click={handleButtonClick}>
Hello 출력
</button>
</div>
<style>
div {
text-align: center;
}
</style>
[실행 결과]
컴포넌트에 이벤트 전달
Svelte에서는 이벤트 디스패처(dispatcher)를 사용하여 이벤트를 전달할 수 있습니다. Svelte는 자식 컴포넌트에서 이벤트가 발생하면 해당 이벤트를 부모 컴포넌트에게 전달하고 부모 컴포넌트에서 구현된 이벤트 처리 함수를 실행합니다.
다음 예제는 자식 컴포넌트에서 click 이벤트가 발생하면 부모 컴포넌트에서 구현된 이벤트 처리 함수를 실행합니다.
[부모 컴포넌트 - App.svelte]
<script>
import ChildComponent from "./Child.svelte";
const handleButtonClick = event => {
console.log(event.detail);
}
</script>
<div>
<ChildComponent on:buttonClick={handleButtonClick}/>
</div>
<style>
div {
text-align: center;
}
</style>
[자식 컴포넌트 - Child.svelte]
<script>
import { createEventDispatcher } from "svelte";
const dispatch = createEventDispatcher();
const sendEvent = () => {
dispatch("buttonClick", "Hello");
}
</script>
<button on:click={sendEvent}>
버튼 클릭
</button>
[실행 결과]
자식 컴포넌트는 svelte의 createEventDispatcher 함수를 호출하여 dispatch를 생성합니다. dispatch는 함수이며, 첫 번째 매개변수로 이벤트 이름을 작성하고 두 번째 매개변수로 이벤트 핸들러 함수에 전달하는 데이터를 설정합니다.
부모 컴포넌트는 on:buttonClick 지시자와 이벤트 핸들러 함수인 handleButtonClick() 함수를 연결합니다. 이벤트가 발생하면 event의 detail 프로퍼티에서 dispatch 함수의 두 번째 매개변수로 설정된 데이터를 확인할 수 있습니다.
만약, 다음과 같이 부모 컴포넌트의 on 지시자의 이름과 dispatch() 함수의 첫 번째 매개변수로 설정된 이벤트 이름이 다른 경우 이벤트 핸들러 함수가 실행되지 않습니다.
[부모 컴포넌트 - App.svelte]
<script>
import ChildComponent from "./Child.svelte";
const handleButtonClick = event => {
console.log(event.detail);
}
</script>
<div>
<ChildComponent on:buttonClick={handleButtonClick}/>
</div>
[자식 컴포넌트 - Child.svelte]
<script>
import { createEventDispatcher } from "svelte";
const dispatch = createEventDispatcher();
const sendEvent = () => {
dispatch("buttonClick123", "Event Call");
}
</script>
<button on:click={sendEvent}>
버튼 클릭
</button>
[실행 결과]
이벤트 포워딩
컴포넌트의 계층구조가 App > B > C로 이루어져 있고, C 컴포넌트에서 이벤트가 발생하는 경우 이벤트는 B 컴포넌트에게만 전달됩니다. 즉, 자식 컴포넌트에서 이벤트가 발생하면 최상위 컴포넌트까지 전달되는 것이 아니라 상위 컴포넌트까지 전달됩니다.
따라서, C 컴포넌트에서 이벤트가 발생하고 이벤트를 처리하는 함수가 App 컴포넌트에 구현되어 있다면, 이벤트 핸들러 함수가 동작하지 않습니다.
[최상위 컴포넌트 - App.svelte]
<script>
import B from "./B.svelte";
const handleButtonClick = event => {
console.log(event.detail);
}
</script>
<div>
<B on:buttonClick={handleButtonClick}/>
</div>
<style>
div {
text-align: center;
}
</style>
[중간 컴포넌트 - B.svelte]
<script>
import C from "./C.svelte";
</script>
<C />
[최하위 컴포넌트 - C.svelte]
<script>
import { createEventDispatcher } from "svelte";
const dispatch = createEventDispatcher();
const sendEvent = () => {
dispatch("buttonClick", "Event Call");
}
</script>
<button on:click={sendEvent}>
버튼 클릭
</button>
[실행 결과]
이 문제를 해결하기 위해 App 컴포넌트와 C 컴포넌트의 다리 역할을 담당하는 B 컴포넌트가 C 컴포넌트에게 수신받은 이벤트를 App 컴포넌트에게 전달해야 합니다.
B 컴포넌트를 다음과 같이 수정합니다.
<script>
import C from "./C.svelte";
</script>
<C on:buttonClick />
이벤트 수정자
이벤트 수정자를 사용하여 이벤트 동작을 제어할 수 있습니다.
다음 예제처럼 once 수정자를 사용하면 click 이벤트가 단 한 번만 실행됩니다.
<script>
const handleButtonClick = event => {
console.log('hello');
}
</script>
<div>
<button on:click|once={handleButtonClick}>버튼</button>
</div>
이벤트 수정자 목록
once - 처음 이벤트 발생 후 이벤트 핸들러 함수를 제거합니다.
capture - 캡처 페이즈에서만 호출됩니다.
passive - 스크롤 성능을 향상할 수 있습니다.
preventDefault - event.preventDefault()를 호출하며, 주로 form의 데이터 전송 이벤트를 발생하지 않도록 하기 위해 사용됩니다.
stopPropagation - event.stopPropagation()을 호출하며, 이벤트의 캡처/버블링 과정에서 다음 단계로 이벤트가 전달되지 않도록 하기 위해 사용됩니다.
'Svelte' 카테고리의 다른 글
[Svelte]스토어 사용 방법 - 쓰기 가능(writable) (0) | 2022.08.03 |
---|---|
[Svelte]콘텍스트를 사용하여 데이터 전달 (0) | 2022.08.02 |
[Svelte]슬롯(slot)이란? (1) | 2022.08.02 |
[Svelte]부모 컴포넌트의 값 변경 (0) | 2022.08.02 |
[Svelte]DOM 요소 참조 방법 (0) | 2022.08.02 |
댓글