스벨트 5 alpha 1이 나오게 되면서 사용을 할수 있게 되었습니다.
스벨트5에서는 지난 몇달 전에 나온 부분대로 rune 이란 체계로 전환 될 예정입니다.
<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>
<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>
배열 등에 값을 다시 받고 넣는 습관을 들이자.
<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>
<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>
기존에 쓰던 $$으로 받아 오던 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 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