svelte 5 alpha 1

sting01·2023년 11월 15일
0

svelte

목록 보기
18/18

스벨트 5 alpha 1이 나오게 되면서 사용을 할수 있게 되었습니다.
스벨트5에서는 지난 몇달 전에 나온 부분대로 rune 이란 체계로 전환 될 예정입니다.

기존 스벨트 let 코드 사용시 $state - 변수 선언, $derived - 함수 선언, $effect - 변환 체크를 기준으로 다시 정립되었습니다.

기존 스벨트

<script lang="ts">
	let width = 10;
	let height = 10;

	$: area = width * height;

	setTimeout(() => {
		width = 20;
		height = 20;
	}, 1000);

	const size = (width: number): number => {
		return width * height;
	};
</script>

<div>
	{width} * {height} = {area}
</div>

<div>
	{size(width)}
</div>

svelte 5

<script>
	let width = $state(10);
	let height = $state(10);

	const area = $derived(size());

	function size() {
		return width * height;
	}

	$effect(() => {
		console.log(area);
	});

	setTimeout(() => {
		width = 20;
		height = 20;
	}, 1000);
</script>

<div>{area}</div>

get 과 set의 필요

배열 등에 값을 다시 받고 넣는 습관을 들이자.

기존 스벨트

<script lang="ts">
	let todos: any[] = [];

	function remaining(todos: any[]) {
		console.log('remaining');
		return todos.filter((todo) => !todo.done).length;
	}

	function addTodo(event) {
		if (event.key !== 'Enter') return;

		let input = event.target as HTMLInputElement;
		let done = false;
		let text = input.value;

		todos = [...todos, { done, text }];

		console.log(todos);

		input.value = '';
	}
</script>

<div>
	<input type="text" on:keydown={addTodo} />
</div>

<ul>
	{#each todos as todo}
		<li>
			<input type="text" bind:value={todo.text} />

			<input type="checkbox" name="" id="" checked={todo.done} />
		</li>
	{/each}

	<p>{remaining(todos)} remaining</p>
</ul>

svelte 5

<script lang="ts">
	let todos = $state<any[]>([]);

	function remaining(todos: any[]) {
		console.log('remaining');
		return todos.filter((todo) => !todo.done).length;
	}

	function addTodo(event) {
		if (event.key !== 'Enter') return;

		let input = event.target as HTMLInputElement;

		let done = $state(false);
		let text = $state(input.value);

		todos = [
			...todos,
			{
				get done() {
					return done;
				},
				set done(value) {
					done = value;
				},
				get text() {
					return text;
				},
				set text(value) {
					text = value;
				}
			}
		];

		console.log(todos);

		input.value = '';
	}
</script>

<div>
	<input type="text" on:keydown={addTodo} />
</div>

<ul>
	{#each todos as todo}
		<li>
			<input type="text" bind:value={todo.text} />

			<input type="checkbox" name="" id="" checked={todo.done} />
		</li>
	{/each}

	<p>{remaining(todos)} remaining</p>
</ul>

spread props

기존에 쓰던 $$으로 받아 오던 property 부분을 개선 해서 받아 올수 있게 정의 되었습니다.
그리고 기존에 쓰던 on: 이벤트에 대한 정의가 onclick, onmouseover, onfocus 등 이벤트 정의가 js와 동일하게 새롭게 정의 되었습니다.
기존 on:이벤트는 사용 가능합니다.

버튼 컴포넌트

<script lang="ts">
	let { ...props } = $props();

	console.log(props);
</script>

<button type="button" {...props}>
	<slot><!-- optional fallback --></slot>
</button>

버튼

<script lang="ts">
	import Buttons from './Buttons.svelte';
</script>

<Buttons
	onclick={() => console.log('click')}
	onmouseover={() => console.log('hover')}
	onfocus={() => console.log('focus')}>클릭</Buttons
>

snippet

태그 정의에 대한 지정을 선언 할수 있게 정의 되었습니다.

{#snippet dom()}
{@render li(item)}

#snippet으로 정의된 부분을 @render로 출력해서 동일한 구조의 형태로 작성 가능하게 되었습니다.

<script lang="ts">
	let items = [1, 2, 3, 4];
	let selected = 1;

	function onSelect(item: number) {
		selected = item;
	}
</script>

<ul>
	{#snippet li(item)}
		<li>
			<button onclick={() => onSelect(item)} area-selected={item === selected}>선택 {item}</button>
		</li>
	{/snippet}
</ul>

<ul>
	{#each items as item}
		{@render li(item)}
	{/each}
</ul>

<style>
	li[area-selected='true'],
	button[area-selected='true'] {
		background-color: blue;
		color: white;
	}
</style>

최근에 스벨트 부분을 못 보고 있는 와중에 alpha 소식이 있어서 작성하였습니다.
올 초에 예고 했던대로 5 부분은 기존에 쓰던 방식에서 많지는 않지만 작성 부분을 바꿔야 하는 게 크지만 migration guide가 나오기 전까지 개인 공부 부분에서는 rune 위주로 작성하는 습관을 들여야 할 것 같습니다.

분명 편해지는 부분도 있는 반면 신경 써야 하는 부분이 늘어난 감이 없지 않나 생각하게 되었습니다.

틀린 부분이 있거나 하면 댓글로 전달주시면 수정하겠습니다.

출처 : https://www.youtube.com/watch?v=gGwnF-lxS_Q&t=196s
https://svelte-5-preview.vercel.app/docs/fine-grained-reactivity

0개의 댓글