LUVIT 새로운 웹 개발의 시작 스벨트2
LUVIT 새로운 웹 개발의 시작 스벨트2
들어가며
이 포스트는 오시내님의 「LUVIT 새로운 웹 개발의 시작 스벨트」 5장부터 10장까지 읽고 개인적으로 학습한 내용을 정리한 글입니다.
- 책: LUVIT 새로운 웹 개발의 시작 스벨트
- 저자: 오시내
- 출판사: 제이펍
- 챕터: 5 ~ 10장
핵심 내용 정리
5장 반응성
삼항 연산자 반응성 코드
1
2
3
4
5
6
7
8
<script>
let count = 1;
const handleClick = () => count++;
</script>
<button on:click={handleClick}>
클릭 수 : {count} { count === 1 ? 'time' : 'times'}
</button>
스크립트 반응성 코드
변수 선언형 반응성 코드
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<script>
let count = 1;
// 반응성 변수 선언
$: doubled = count * 2;
$: square = count * count;
const handleClick = () => count++;
</script>
<button on:click={handleClick}>
클릭 수 : {count}
</button>
<h3>두 배 구하기</h3>
<p> {count } x 2 = {doubled}</p>
<h3>제곱 구하기</h3>
<p> {count} x {count} = {square}</p>
$:의 그룹화
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<script>
let count = 1;
// 반응성 변수 선언
$: doubled = count * 2;
$: square = count * count;
$: {
console.log('두 배 값:' + doubled);
console.log('제곱 값:' + square);
}
const handleClick = () => count++;
</script>
<button on:click={handleClick}>
클릭 수 : {count}
</button>
<h3>두 배 구하기</h3>
<p> {count } x 2 = {doubled}</p>
<h3>제곱 구하기</h3>
<p> {count} x {count} = {square}</p>
$:조건절
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<script>
let count = 1;
$: if(count >= 10){
alert('10개 이상 구매할 수 없다');
count = 9;
}
$: if(count <= 0>){
alert('최소 구매 개수 1개');
count = 1;
}
const plusHandle = () => count++;
const minusHandle = () => count--;
</script>
<button on:click={minusHandle}>-</button>
<input type="text" value="{count}">
<button on:click={plusHandle}>-</button>
6장 이벤트 문법
스벨트 이벤트 사용 방법
1
2
3
4
5
6
7
8
9
10
11
12
13
<script>
let m = {x:0, y: 0};
const handleMouseMove = e =>{
m.x = e.clientX;
m.y = e.clientY;
}
</script>
<div on:mousemove={handleMouseMove} role="presentation">
x 좌표 : {m.x} <br>
y 좌표 : {m.y}
</div>
인라인 이벤트 사용 방법
1
2
3
4
5
6
7
8
9
<script>
let m = {x:0, y: 0};
</script>
<div on:mousemove={e => m = {x:clientX, y : e.clientY}} role="presentation">
x 좌표 : {m.x} <br>
y 좌표 : {m.y}
</div>
함수 매개변수 사용
1
2
3
4
5
6
7
<script>
const handleClick01 = text => alert(`${text} 클릭!`);
const handleClick02 = text => alert(`${text} 클릭!`);
</script>
<button on:click={() => handleClick01('1번')}> 첫 번째 버튼</button>
<button on:click={() => handleClick02('2번')}> 두 번째 버튼</button>
once 수식어 사용
1
2
3
4
5
6
7
<script>
const handleClick01 = () => alert('클릭은 한번만');
const handleClick02 = () => alert('클릭 계속');
</script>
<button on:click|once={handleClick01}>클릭01</button>
<button on:click={handleClick02}>클릭02</button>
preventDefault 수식어
1
2
3
4
5
6
7
8
9
10
<script>
const handleClick = () =>{
let move = confirm('제이펍 사이트로 이동?');
move && location.assign('http://jpub.kr');
}
</script>
<h1>
<a href="http://jpub.kr" on:click|preventDefault={handleClick}>제이펍 출판사</a>
</h1>
7장 props(25-07-09 작성)
props
- 부모 컴포넌트가 자손 컴포넌트에게 전달하는 값
- 컴포넌트가 자식, 부모 컴포넌트로 제적해야함
1
2
3
4
5
6
7
8
9
10
11
12
// 자식 컴포넌트
<script>
export let name;
export let age;
export let hobby;
</script>
<h3>이름 : {name}</h3>
<h3>나이 : {age}</h3>
<h3>취미 : {hobby}</h3>
1
2
3
4
5
6
7
8
9
10
// 부모 컴포넌트
<script>
import child01 from "./child01.svelte";
</script>
<child01 name={'김철수'} age = {20} hobby = {'축구하기'}>
<child01 name="이영희" age = 21 hobby = "넷플릭스보기">
props 기본값 설정
1
2
3
4
5
6
7
8
9
10
11
12
// 자식 컴포넌트
<script>
export let name = " 홍길동";
export let age = 20;
export let hobby = "독서";
</script>
<h3>이름 : {name}</h3>
<h3>나이 : {age}</h3>
<h3>취미 : {hobby}</h3>
props 데이터 변경
1
2
3
4
5
6
7
8
9
10
11
12
// 자식 컴포넌트
<script>
export let name = " 홍길동";
export let age = 20;
export let hobby = "독서";
</script>
<h3>이름 : {name}</h3>
<h3>나이 : {age}</h3>
<h3>취미 : {hobby}</h3>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<script>
import child01 from "./child01.svelte"
let age01 = 20;
let age02 = 21;
const agePlus = () =>{
age01++;
age02++;
}
const ageMinus = () =>{
age01--;
age02--;
}
</script>
<child01 name={'김철수'} age = {20} hobby = {'축구하기'}>
<child01 name="이영희" age = 21 hobby = "넷플릭스보기">
<button on:click={ageMinus}>나이 감소-</button>
<button on:click={agePlus}>나이 증가+</button>
스프레드 props
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// 자식 컴포넌트
<script>
import child03 from "./child03.svelte";
const allData01 = {
name: '김철수',
age: 20,
hobby: '축구하기'
}
</script>
<h3>이름 : {name}</h3>
<h3>나이 : {age}</h3>
<h3>취미 : {hobby}</h3>
<child03 {...allData01}>
<child03 {...allData02}>
8장 스벨트 로직(25-07-10 작성)
if, else-if, else 블록 기본 문법
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<script>
let x = null;
const numChange = e => x = e.target.value;
</script>
<label for="testBox">양수/음수 테스트</label>
<input type="text" id="testBox" on:keyup={numChange} placeholder="정수를 입력하세요.">
{#if x > 0}
<p>작성한 숫자는 양수입니다.</p>
{:else if x < 0}
<p>작성한 숫자는 음수입니다.</p>
{:else if x === '0'}
<p>작성한 숫자는 0입니다.</p>
{:else}
<p>정수로 다시 입력하세요.</p>
{/if}
each 블록 기본 문법 전체
1
2
3
4
5
6
7
8
<script>
let teams = ['LG 트윈스','KT 위즈','SSG 랜더스','NC 다이노스','두산 베어스','KIA 타이거즈','롯데 자이언츠','삼성 라이온즈','한화 이글스','키움 히어로즈'];
</script>
<h3>2023 KBO 정규리그 순위</h3>
{#each teams as team,i}
<p>{i + 1}위 : {team}</p>
{/each}
객체 데이터 반복문
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
<script>
let langs = [
{
id: 1,
name: '스벨트(Svelte)',
release: 2016,
src: 'https://svelte.dev/favicon.png',
},
{
id: 2,
name: '리액트(React)',
release: 2013,
src: 'https://ko.legacy.reactjs.org/favicon.ico',
},
{
id: 3,
name: '뷰(Vue.js)',
release: 2013,
src: 'https://v2.ko.vuejs.org/images/logo.png',
}
];
</script>
<h3>웹 프론트엔드 언어</h3>
{#each langs as lang (lang.id) }
<div style="border: 2px solid black; width: 200px; padding: 10px;">
<h4>이름 : { lang.name }</h4>
<p>배포 년도 : { lang.release }년</p>
<img src={ lang.src } alt={ lang.name } height="50">
</div>
{/each}
9장 폼 관련 요소 바인딩
- 바인딩 : 상태값과 그 값을 제어하는 요소 간의 결합
- 단방향 바인딩 : 요소가 상태값을 직접 변화시키지 못함. props가 예시
- 양방향 바인딩 : 입력과 출력이 동시에 변경되도록 처리
입력 요소 관련 바인딩
input값 바인딩 - text, number, checkbox, radio, textarea 버튼
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<script>
let name = '';
let a = 1;
let b = 2;
let chk = false;
</script>
<input type="text" bind:value={name} placeholder="이름을 입력하세요.">
<p>안녕! {name || '낯선 사람'}!</p>
<label>
<input type="number" bind:value={a} min="0" max="10">
<input type="range" bind:value={a} min="0" max="10">
</label>
<label>
<input type="number" bind:value={b} min="0" max="10">
<input type="range" bind:value={b} min="0" max="10">
</label>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
<script>
let chk = false;
let choiceSize = 0;
let sizes = ['Tall','Grande','Venti'];
let text = '내용을 입력하세요.';
</script>
<label>
<input type="checkbox" bind:checked={chk}> 약관 동의
</label>
{#if chk}
<p>당신은 약관에 동의했습니다.<br>이제 구독이 가능합니다.</p>
{:else}
<p>당신은 약관에 동의하지 않았습니다.<br>아직 구독이 불가능합니다.</p>
{/if}
<button disabled={!chk}>
구독
</button>
<h3>사이즈 선택</h3>
{#each sizes as size, i}
<label>
<input type="radio" bind:group={choiceSize} value={i}>
{ size }
</label>
{/each}
<p>고객님은 {sizes[choiceSize]}를 선택하셨습니다.</p>
<textarea bind:value={text} rows="5" />
<p>{text}</p>
선택 바인딩
select 값 바인딩 - 단일 선택 ```javascript
const selectChange = () => { if(selected != null){ window.open(selected); } } </script>
포털 사이트 바로가기
<select bind:value={selected} on:change={selectChange}> {#each portals as portal} <option value={portal.url}>{ portal.name }</option> {/each} </select>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
- select 값 바인딩 - 다중 선택
```javascript
<script>
let foods = ['떡볶이','순대','오뎅','튀김'];
let selected = '';
</script>
<h3>OSSAM 분식</h3>
<select multiple bind:value={selected}>
{#each foods as food}
<option value={food}>{ food }</option>
{/each}
</select>
{#if selected.length === 0}
<p>주문하실 메뉴를 선택해 주세요.</p>
{:else}
<p>선택 메뉴 : {selected}</p>
{/if}
10장 기타 요소 바인딩
- 바인딩 방법 & 이벤트 처리 함수 추가하기
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<script>
let buckets = [
{ chk: false, text: '웹 프론트엔드 개발자되기' },
{ chk: false, text: '유럽 여행하기' },
{ chk: false, text: '영국 가서 손흥민 축구 경기 보기' }
];
$: remaining = buckets.filter(bucket => !bucket.chk).length;
const onAdd = () => {
buckets = buckets.concat({ chk: false, text: '' });
}
const onRemove = () => {
buckets = buckets.filter(bucket => !bucket.chk);
}
</script>
<h1>Bucket List</h1>
{#each buckets as bucket}
<div>
<input type="checkbox" bind:checked={bucket.chk} />
<input type="text" placeholder="당신의 버킷 리스트는 뭔가요?" style="width: 250px" bind:value={bucket.text} disabled={bucket.chk} />
</div>
{/each}
<p>남은 버킷 리스트 : {remaining}</p>
<button on:click={onAdd}>새로운 버킷 추가</button>
<button on:click={onRemove}>성공한 버킷 제거</button>
멀티미디어 요소 바인딩
- 멀티미디어 요소(video 등) 바인딩
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
<script>
let duration;
let currentTime = 0;
let paused = true;
const onPlay = () => paused = false;
const onPause = () => paused = true;
const onInitial = () => {
paused = true;
currentTime = 0;
}
</script>
<h1>Caminandes: Llamigos</h1>
<p>From <a href="https://studio.blender.org/films">Blender Studio</a>. CC-BY</p>
<video
poster="https://sveltejs.github.io/assets/caminandes-llamigos.jpg"
src="https://sveltejs.github.io/assets/caminandes-llamigos.mp4"
width="500"
bind:duration={duration}
bind:currentTime={currentTime}
bind:paused={paused}
>
<track kind="captions" />
</video>
<br />
<button on:click={onPlay}>재생</button>
<button on:click={onPause}>멈춤</button>
<button on:click={onInitial}>초기화</button>
<p>총 재생 시간 : {duration}초</p>
<p>현재 재생 위치 : {currentTime}초</p>
공간 바인딩
- 블록 요소 바인딩
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<script>
let w;
let h;
let size = 20;
</script>
<p>슬라이더로 글자 크기를 변경해보세요.</p>
<input type="range" bind:value={size} min="10" max="100" />
<p>글자 크기 : {size}px</p>
<div bind:clientWidth={w} bind:clientHeight={h}>
<span style="font-size: {size}px">글자</span>
</div>
<ul>
<li>가로 폭 : {w}</li>
<li>세로 높이 : {h}</li>
</ul>
<style>
div{ display: inline-block; border: 3px solid black; }
</style>
this 바인딩
- 특정 DOM을 선택하는 방법 -> bind:this 사용하기
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
// this.svelte
<script>
let text = '';
let clicked = false;
let validated = false;
let inputRef;
const onValidatedClick = () => {
clicked = true;
validated = text === '1234';
if(!validated){
inputRef.focus();
}
}
</script>
<form>
<input
type="password" bind:value={text}
class={clicked && (validated ? 'success' : 'failure')}
bind:this={inputRef}
/>
<button
type="submit"
on:click|preventDefault={onValidatedClick}
>검증하기</button>
</form>
<style>
.success{ background-color: lightgreen; }
.failure{ background-color: lightcoral; }
</style>
// App.svelte
<script>
import This from './This.svelte'
</script>
<This/>
<This/>
<This/>
컴포넌트 바인딩
- 컴포넌트의 props를 바인딩하는 방법
- bind를 사용해 부모 컴포넌트의 상태변수와 자식 컴포넌트의 상태변수를 연결
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// Parent.svelte
<script>
import Child from "./Child.svelte";
let parentValue = 1;
</script>
<Child bind:childValue={parentValue} />
<p>부모 값 : {parentValue}</p>
// App.svelte
<script>
import Parent02 from "./Parent02.svelte";
</script>
<Parent02 />
스벨트 slot
This post is licensed under CC BY 4.0 by the author.