<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
<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>
once를 삽입하면 최초 한 번만 이벤트가 발생한다.
즉, alert이벤트가 버튼을 한 번 클릭한 후 더 클릭해도 발생하지 않는다.
<script>
function handleClick() {
alert('no more alerts');
}
</script>
<button on:click|once={handleClick}> Click me </button>
<script>
import Inner from './Inner.svelte';
function handleMessage(event) {
alert(event.detail.text);
}
</script>
<Inner on:message={handleMessage} />
이 코드는 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 />
Inner.svelte에서 createEventDispatcher를 사용해 message라는 커스텀 이벤트를 발생시킨다.dispatch('message', { text: 'Hello!' })는 message라는 이벤트를 발생시키고, 그 이벤트에 text: 'Hello!'라는 데이터를 전달한다.message 이벤트가 발생하고, 이 이벤트는 상위 컴포넌트(Outer.svelte)로 전파된다.Outer.svelte 이벤트 포워딩Outer.svelte는 이벤트 핸들러를 직접 제공하지 않고 <Inner on:message />를 사용하여 Inner 컴포넌트의 message 이벤트를 그대로 상위로 포워딩한다.Svelte는 이 구문을 통해 Inner에서 발생한 message 이벤트를 자동으로 포워딩한다. 즉, Outer.svelte가 자체적으로 이벤트를 처리하지 않지만, message 이벤트가 상위로 전달될 수 있도록 해준다.App.svelte 이벤트 처리App.svelte는 Outer.svelte에서 포워딩된 message 이벤트를 수신하고, handleMessage 함수에서 처리한다.event.detail.text를 통해 Inner.svelte에서 전달된 데이터를 접근할 수 있고, 이 데이터를 사용해 alert('Hello!')를 띄우는 동작을 한다.<Inner on:message />에서 on:message는 Svelte에서 이벤트 리스너를 설정하는 구문이다. 이 구문은 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가 기본적으로 하위 컴포넌트에서 발생한 이벤트를 상위 컴포넌트로 전달하는 메커니즘을 내장하고 있기 때문이다.Svelte는 DOM 이벤트의 버블링을 이용해 이벤트가 상위로 전파될 수 있도록 도와준다. 이로 인해 상위 컴포넌트에서 이벤트를 다시 수신하고 처리할 수 있게 된다.on:message는 Inner.svelte에서 발생한 message 이벤트를 상위 컴포넌트로 포워딩하기 위한 Svelte의 구문이다.<!-- 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>
그냥 스타일 적용한 버튼에 알람창 달아놓는 것.
클릭 이벤트를 상위 컴포넌트에서 지정해주고 하위컴포넌트가 받는 형식.