Svelte 입문 강의 - A부터 Z까지 2

2️⃣

🖥 Props

3 - 1. 정의 방법

// 부모 컴포넌트
<script>
import Child from './Child.svelte'
</script>

<Child test="JJ입니다." />

// 자식 컴포넌트
<script>
export let test;
</script>

<p>{test}</p>

// 부모컴포넌트에서 자식 컴포넌트로 props 전달이 가능하다

3 - 2. 기본값 설정

// 부모 컴포넌트
<script>
import Child from './Child.svelte'
</script>

<Child name="JJ"></Child>
<Child></Child>

//자식 컴포넌트
<script>
export let name = "nope";
</script>

<p>이름은 {name} 입니다</p>
이름은 JJ 입니다
이름은 nope 입니다

3 - 3. Spread 문법 사용하기

// 부모 컴포넌트
<script>
	import Child from './Child.svelte'

	let name = "jj";
	let job = "developer"
	let website = "https://jina95.github.io/"
</script>

<Child {name} {job} {website}></Child>

// 자식 컴포넌트
<script>
export let name;
export let job;
export let website;
</script>

<p>{name}, {job}, {website}</p>

<Child name = {name} {job} {website}></Child>

// 부모 컴포넌트
<script>
    import Child from './Child.svelte'
    let info = {
		name : "jj",
		job : "developer",
		website : "https://jina95.github.io/"
	}
</script>

<Child {...info}></Child>

🖥 논리 블록

4 - 1. 조건문 블록

{#if x > 10}
	<p>{x} 10보다 큽니다</p>
{:else if x > 5}
	<p>{x} 5보다 큽니다</p>
{:else}
	<p>{x} 5보다 작습니다</p>
{/if}

4 - 2. 반복문 블록

<script>
	let list = [
		{id: 1, text: 'test 1'},
		{id: 2, text: 'test 2'},
		{id: 3, text: 'test 3'},
	]
</script>


<ul>
	{#each list as item, i}
	<li>{i}: {item.id}, {item.text}</li>
	{/each}
</ul>

// 구조문법을 이용해서 아래와 같이 나타낼수도있다.
<ul>
	{#each list as {id, text}, i}
	<li>{i}: {id}, {text}</li>
	{/each}
</ul>

4 - 3. 반복문 블록에 Key 지정하기

<script>
	let list = [
		{id: 1, text: 'test 1'},
		{id: 2, text: 'test 2'},
		{id: 3, text: 'test 3'},
	]

	function addItem(){
		const id = Math.max(...list.map(x => x.id)) + 1;
		list = [...list, {id, text: `test${id}`}];
	}

	function removeItem(){
		list.shift();
		list = list;
	}

	function resetItem(){
		list = [
			{ id: 1, text: 'test 1' },
			{ id: 2, text: 'test 2' },
			{ id: 3, text: 'test 3' },
		]
	}
</script>

<button on:click={ addItem }>Add</button>
<button on:click={ removeItem }>Remove</button>
<button on:click={ resetItem }>Reset</button>

<ul>
	{#each list as item (item.id)}
	<li>{item.id}, {item.text}</li>
	{/each}
</ul>

4 - 4. await 블록

<script>
	let promise;
	function sayHello(){
		return new Promise((resolve,reject) => {
			setTimeout(()=> {
				// resolve('Hello World');
				reject(new Error('에러발생!'))
			}, 1000)
		})
	}
	function handleClick(){
		promise = sayHello();
	}
</script>


<button on:click={handleClick}>인사하기</button>

{#await promise}
	<p>인사를 기다리는 ...</p>
{:then data}
	<p>{data}</p>
{:catch error}
	<p>{error.message}</p>
{/await}
{#await promise then data}
	<p>{data}</p>
{/await}

🖥 이벤트 다루기

5 - 1. DOM 이벤트

<script>
	let m = { x:0, y:0}
	let isEnter = false;
	function handleMousemove(event){
		m.x = event.clientX;
		m.y = event.clientY;
	}

	function handleMouseenter() {
		isEnter = true;
	}

	function handleMouseleave(){
		isEnter = false;
	}
</script>


<div on:mousemove={handleMousemove}>
	마우스 위치 : {m.x}, {m.y}
	<div 
		on:mouseenter={handleMouseenter}
		on:mouseleave={handleMouseleave}
		>
		{ isEnter ? 'Enter' : 'Leave'}
	</div>
</div>


<style>
	div {
		width: 100%;
		height: 100%;
	}
	div > div {
		width: 100px;
		height: 100px;
		background-color: yellow;
	}
</style>

5 - 2. 인라인 핸들러

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

<div on:mousemove={e => m = {x : e.clientX, y: e.clientY}}>
	마우스 위치 : {m.x}, {m.y}
</div>

5 - 3. 이벤트 수식어

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

<button on:click|once={handleClick}>
	Click
</button>
preventDefault: 이벤트 핸들러가 실행되기 전 event.preventDefault()를 호출합니다. 태그의 기본 동작을 막는 이벤트 수식어입니다.
stopPropagation: event.stopPropagation()이 호출됩니다. 이벤트가 다음 요소로 흐르는 것을 막는 이벤트 수식어입니다.
passive: 터치 혹은 휠 이벤트로 발생하는 스크롤 성능을 향상시키는 이벤트 수식어입니다. Svelte는 안전한 곳(?)에 자동으로 추가합니다.
capture: 버블링 단계가 아닌 캡처 단계에서 이벤트 핸들러를 실행합니다.
once: 이벤트 핸들러를 단 한 번만 실행하도록 하는 이벤트 수식어입니다.
self: event.target과 이벤트 핸들러를 정의한 요소가 같을 때 이벤트 핸들러를 실행하도록 하는 이벤트 수식어입니다.

위의 이벤트 수식어를 on:click|once|capture={...}와 같이 체인(chain)으로 연결해 여러 개를 정의할 수도 있습니다

5 - 4. 컴포넌트 이벤트

// 부모 컴포넌트
<script>
import Child from './Child.svelte'

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

<Child on:message={handleMessage}></Child>

// 자식 컴포넌트
<script>
    import { createEventDispatcher } from 'svelte'

    const dispatch = createEventDispatcher();

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

<button on:click={sayHello}>Click</button>

5 - 5. 컴포넌트 이벤트 발생시 주의사항

// 추가된 컴포넌트
<script>
    import Child from './Child.svelte'
    import { createEventDispatcher } from 'svelte'

    const dispatch = createEventDispatcher();

    function handleMessage(event) {
        dispatch('message', event.detail.text)
    }
</script>

<Child on:message={handleMessage}/>
// 하지만 아래와 같이 수정해도 가능하다고 하는데, 내가 했을땐 뭔가 잘 안됬다..

<script>
    import Child from './Child.svelte'
</script>

<Child on:message/>