사이트가 복잡해져 가면 component 를 잘게 찢어서 사용하기에 한계가 있다. 이유는 상위 parent component 에서 하위 childe component 를 호출하는 거야 문제가 없겠지만, 하위 child component 내부에서 변경된 변수값을 상위 parent 에 전달하기 복잡하다.
복잡하지만 그래도 사이트를 만들어야 하니 해야지..
참조페이지
https://svelte.dev/examples/component-bindings
1. dispatcher 사용
참조 페이지 : https://svelte.dev/tutorial/component-events
자주 애용하지만 복잡하다. vuejs 에서 $emit()과 거의 같은 역할을 한다. vuejs 를 하다 보니 아래 $emit과 동일한 걸 찾느라 bind를 보지 못했던 것 같다.
다만 변수명을 어떻게 했더라?? 하고 헤깔리는 경우가 많다. 사용법은 아래와 같다.
parent component
<script>
import Inner from './Inner.svelte';
function handleMessage(event) {
alert(event.detail.text);
}
</script>
<Inner on:message={handleMessage}/>
child component
<script>
import { createEventDispatcher } from 'svelte';
const dispatch = createEventDispatcher();
function sayHello() {
dispatch('message', { text: 'Hello!' });
}
</script>
<button on:click={sayHello}>
Click to say hello
</button>
child component에서 dispatcher 를 선언하고, parent 에서 받을 이벤트명과 값을 지정한다.
상위부모 컴포넌트에서는 on:eventname={callback} 함수 형태로 이벤트 발생시 실행할 함수 콜백명을 지정하고, 해당 함수에서 event 값을 받으면 된다. 단, 주의할 사항은 변수로 넘어온 값이 단순한 값이 아니고 객체 구조에 포함된 값이기 때문에, e.detail 이하에 해당 값이 포함되어 있다.
아래 bind를 알고 나서는 부모 컴포넌트의 함수 호출용으로만 사용 중이다.
2. bind를 이용한 방법
svelte에서 권장하는 방법이지만, 영어가 짧은 관계로 잘 못알아 먹고 이제서야 해보는 방법이다. ㅠ,.ㅠ;
https://svelte.dev/examples/component-bindings
parent component
<script>
import Keypad from './Keypad.svelte';
let pin;
$: view = pin ? pin.replace(/\d(?!$)/g, '•') : 'enter your pin';
function handleSubmit() {
alert(`submitted ${pin}`);
}
</script>
<h1 style="color: {pin ? '#333' : '#ccc'}">{view}</h1>
<Keypad bind:value={pin} on:submit={handleSubmit}/>
child component
<script>
import { createEventDispatcher } from 'svelte';
export let value = '';
const dispatch = createEventDispatcher();
const select = num => () => value += num;
const clear = () => value = '';
const submit = () => dispatch('submit');
</script>
<div class="keypad">
<button on:click={select(1)}>1</button>
<button on:click={select(2)}>2</button>
<button on:click={select(3)}>3</button>
<button on:click={select(4)}>4</button>
<button on:click={select(5)}>5</button>
<button on:click={select(6)}>6</button>
<button on:click={select(7)}>7</button>
<button on:click={select(8)}>8</button>
<button on:click={select(9)}>9</button>
<button disabled={!value} on:click={clear}>clear</button>
<button on:click={select(0)}>0</button>
<button disabled={!value} on:click={submit}>submit</button>
</div>
<style>
.keypad {
display: grid;
grid-template-columns: repeat(3, 5em);
grid-template-rows: repeat(4, 3em);
grid-gap: 0.5em
}
button {
margin: 0
}
</style>
간단히 말해서 그냥 bind로 묶어 주면 된다. 상위 부모 컴포넌트에서 사용하는 변수를 하위 자식 컴포넌트에서 사용하는 변수명과 묶어 주면 된다.
bind:value={pin}. value=자식이 사용하는 변수명, {pin}=부모가 사용 중인 변수명
별거 없다. 그냥 연동되더라. dispatcher를 사용하던 시절이 한탄스럽기만 하더라
실무에 많은 도움이 되었기를... 적어도 난 도움이 많이 되었다는 거.. ^^