Svelte 입문 (Events)

Shy·2024년 9월 23일

Svelte

목록 보기
3/12

Events

DOM events

<script>
	let m = { x: 0, y: 0 };

	function handleMousemove(event) {
		m.x = event.clientX;
		m.y = event.clientY;
	}
</script>

<!-- svelte-ignore a11y-no-static-element-interactions -->
<div on:mousemove={handleMousemove}>
	The mouse position is {m.x} x {m.y}
</div>

<style>
	div {
		width: 100%;
		height: 100%;
	}
</style>
The mouse position is 232 x 27

Inline handlers

<script>
	let m = { x: 0, y: 0 };
</script>

<!-- svelte-ignore a11y-no-static-element-interactions -->
<div on:mousemove={(e) => (m = { x: e.clientX, y: e.clientY })}>
	The mouse position is {m.x} x {m.y}
</div>

<style>
	div {
		width: 100%;
		height: 100%;
	}
</style>

Event modifiers

once를 삽입하면 최초 한 번만 이벤트가 발생한다.
즉, alert이벤트가 버튼을 한 번 클릭한 후 더 클릭해도 발생하지 않는다.

<script>
	function handleClick() {
		alert('no more alerts');
	}
</script>

<button on:click|once={handleClick}> Click me </button>

Component events

<script>
	import Inner from './Inner.svelte';

	function handleMessage(event) {
		alert(event.detail.text);
	}
</script>

<Inner on:message={handleMessage} />

Event forwarding

이 코드는 Svelte의 이벤트 포워딩 메커니즘을 보여주는 예제이다. 각 컴포넌트가 상위 컴포넌트로 이벤트를 "포워딩"하여 상위 컴포넌트에서 이벤트를 처리할 수 있도록 설계되어 있다. 이 예제에서 Inner 컴포넌트에서 발생한 message 이벤트가 Outer 컴포넌트를 거쳐 최종적으로 App.svelte에서 처리된다.

DOM 이벤트와 달리, 컴포넌트 이벤트는 버블링되지 않는다.
즉, Inner -> Outer -> App식으로 컴포넌트가 작동해야 할 때, Innser에서 발생한 이벤트는 Outer까지만 전송된다.
이것을 App까지 올리려면 Outer에도 동일하게 dispatcher를 생성하고 상위로 던지는 로직을 추가해야 한다.

<!-- App.svelte -->
<script>
	import Outer from './Outer.svelte';

	function handleMessage(event) {
		alert(event.detail.text);
	}
</script>

<Outer on:message={handleMessage} />
<!-- Inner.svelte -->
<script>
	import { createEventDispatcher } from 'svelte';

	const dispatch = createEventDispatcher();

	function sayHello() {
		dispatch('message', {
			text: 'Hello!'
		});
	}
</script>

<button on:click={sayHello}> Click to say hello </button>
<!-- Outer.svelte -->
<script>
	import Inner from './Inner.svelte';
</script>

<Inner on:message />
  1. Inner.svelte에서 createEventDispatcher를 사용해 message라는 커스텀 이벤트를 발생시킨다.
    • dispatch('message', { text: 'Hello!' })message라는 이벤트를 발생시키고, 그 이벤트에 text: 'Hello!'라는 데이터를 전달한다.
    • 버튼 클릭 시, message 이벤트가 발생하고, 이 이벤트는 상위 컴포넌트(Outer.svelte)로 전파된다.
  2. Outer.svelte 이벤트 포워딩
    • Outer.svelte는 이벤트 핸들러를 직접 제공하지 않고 <Inner on:message />를 사용하여 Inner 컴포넌트의 message 이벤트를 그대로 상위로 포워딩한다.
    • Svelte는 이 구문을 통해 Inner에서 발생한 message 이벤트를 자동으로 포워딩한다. 즉, Outer.svelte가 자체적으로 이벤트를 처리하지 않지만, message 이벤트가 상위로 전달될 수 있도록 해준다.
  3. App.svelte 이벤트 처리
    • App.svelteOuter.svelte에서 포워딩된 message 이벤트를 수신하고, handleMessage 함수에서 처리한다.
    • event.detail.text를 통해 Inner.svelte에서 전달된 데이터를 접근할 수 있고, 이 데이터를 사용해 alert('Hello!')를 띄우는 동작을 한다.

Inner on

<Inner on:message />에서 on:messageSvelte에서 이벤트 리스너를 설정하는 구문이다. 이 구문은 Svelte의 이벤트 바인딩 방식으로, Inner 컴포넌트에서 발생한 message라는 이벤트를 상위 컴포넌트로 포워딩하는 역할을 한다.

Svelte에서 on:이벤트이름 구문을 사용하면, 해당 컴포넌트에서 발생한 특정 이벤트를 리스닝할 수 있다.

  • on:message의 역할
    • <Inner on:message />Inner.svelte에서 발생한 message 이벤트를 포워딩하는 구문이다.
    • on:message={} 부분에 이벤트 핸들러를 작성하지 않았지만, Svelte는 자동으로 이 이벤트를 상위 컴포넌트로 포워딩한다.
    • 즉, Inner.svelte에서 발생한 message 이벤트가 Outer.svelte로 전달되며, Outer.svelte가 이를 다시 App.svelte로 포워딩할 수 있게 된다.
    • 이런 방식은 상위 컴포넌트에서 이벤트 핸들러를 직접 정의하지 않고, 하위에서 발생한 이벤트를 자동으로 포워딩하여 상위 컴포넌트에서 처리할 수 있게 해준다.
  • on:message만으로 동작할까?
    • 보통 on:이벤트이름={함수}처럼 이벤트와 핸들러를 함께 작성하지만, 포워딩의 경우에는 on:이벤트이름만으로도 동작한다. 이 이유는 Svelte기본적으로 하위 컴포넌트에서 발생한 이벤트를 상위 컴포넌트로 전달하는 메커니즘을 내장하고 있기 때문이다.
    • 이벤트가 발생하면 SvelteDOM 이벤트의 버블링을 이용해 이벤트가 상위로 전파될 수 있도록 도와준다. 이로 인해 상위 컴포넌트에서 이벤트를 다시 수신하고 처리할 수 있게 된다.
  • 정리하자면
    • on:messageInner.svelte에서 발생한 message 이벤트를 상위 컴포넌트로 포워딩하기 위한 Svelte의 구문이다.
    • 이벤트 핸들러를 따로 정의하지 않아도 Svelte가 자동으로 이벤트를 상위로 전달해준다.

DOM event forwarding

<!-- App.svelte -->
<script>
	import CustomButton from './CustomButton.svelte';

	function handleClick() {
		alert('clicked');
	}
</script>

<CustomButton on:click={handleClick} />
<!-- CustomButton.svelte -->
<button on:click> Click me </button>

<style>
	button {
		height: 4rem;
		width: 8rem;
		background-color: #aaa;
		border-color: #f1c40f;
		color: #f1c40f;
		font-size: 1.25rem;
		background-image: linear-gradient(45deg, #f1c40f 50%, transparent 50%);
		background-position: 100%;
		background-size: 400%;
		transition: background 300ms ease-in-out;
	}
	button:hover {
		background-position: 0;
		color: #aaa;
	}
</style>

그냥 스타일 적용한 버튼에 알람창 달아놓는 것.
클릭 이벤트를 상위 컴포넌트에서 지정해주고 하위컴포넌트가 받는 형식.

profile
신입사원...

0개의 댓글