Files
2nd/10_Wiki/Topics/Coding/Frontend_Vue3_Svelte5_Patterns.md
T
2026-05-10 22:08:15 +09:00

6.3 KiB

id, title, category, status, source_trust_level, verification_status, created_at, updated_at, tags, tech_stack, applied_in, aliases
id title category status source_trust_level verification_status created_at updated_at tags tech_stack applied_in aliases
frontend-vue3-svelte5-patterns Vue 3 / Svelte 5 — modern composition / runes Coding draft B conceptual 2026-05-09 2026-05-09
frontend
vue
svelte
vibe-coding
language applicable_to
TS
Frontend
Vue 3
Composition API
Pinia
Svelte 5
runes
$state
Nuxt
SvelteKit

Vue 3 / Svelte 5

React 의 alternative. Vue 3 (composition API), Svelte 5 (runes — signal식). Modern reactivity.

📖 핵심 개념

  • Vue: composition API (React hooks 비슷).
  • Svelte 5: runes (signal-based).
  • 둘 다 modern reactivity.
  • SSR 친화 (Nuxt, SvelteKit).

💻 코드 패턴

Vue 3 SFC (Single File Component)

<script setup lang='ts'>
import { ref, computed } from 'vue';

const count = ref(0);
const double = computed(() => count.value * 2);

function increment() {
  count.value++;
}
</script>

<template>
  <button @click='increment'>{{ count }} ({{ double }})</button>
</template>

<style scoped>
button { padding: 8px; }
</style>

→ Template + script + style.

Vue Composition API

import { ref, reactive, computed, watch, onMounted } from 'vue';

const count = ref(0);            // primitive
const user = reactive({ name: '' });  // object
const double = computed(() => count.value * 2);

watch(count, (newVal, oldVal) => {
  console.log('count:', newVal);
});

onMounted(() => {
  console.log('mounted');
});

→ React hooks 비슷.

Vue composable (custom hook)

// composables/useCounter.ts
export function useCounter(initial = 0) {
  const count = ref(initial);
  const inc = () => count.value++;
  return { count, inc };
}

// 사용
const { count, inc } = useCounter();

Pinia (Vue 의 Zustand)

import { defineStore } from 'pinia';

export const useUserStore = defineStore('user', {
  state: () => ({ name: '', age: 0 }),
  actions: {
    setName(name: string) { this.name = name; },
  },
  getters: {
    isAdult: (state) => state.age >= 18,
  },
});

// 사용
const store = useUserStore();
store.setName('Alice');
console.log(store.isAdult);

Nuxt (Vue 의 Next)

<!-- pages/users/[id].vue -->
<script setup>
const route = useRoute();
const { data } = await useFetch(`/api/users/${route.params.id}`);
</script>

<template>
  <h1>{{ data.name }}</h1>
</template>

→ File-based route + SSR/SSG/edge.

Svelte 5 (runes)

<script>
  let count = $state(0);
  let double = $derived(count * 2);
  
  $effect(() => {
    console.log('count:', count);
  });
  
  function increment() {
    count++;
  }
</script>

<button onclick={increment}>{count} ({double})</button>

<style>
  button { padding: 8px; }
</style>

$state / $derived / $effect = runes.

Svelte 5 의 변화

Svelte 4: implicit reactivity (let, $:).
Svelte 5: explicit ($state, $derived).

→ 더 명시적. Compile-time.

SvelteKit (Svelte 의 Next)

<!-- routes/users/[id]/+page.svelte -->
<script>
  let { data } = $props();
</script>

<h1>{data.name}</h1>
// routes/users/[id]/+page.server.ts
export async function load({ params }) {
  const user = await fetchUser(params.id);
  return { name: user.name };
}

Vue vs React vs Svelte

Vue:
- Template (HTML-friendly).
- Composition API (modern).
- 큰 ecosystem.
- Pinia / Vue Router.

Svelte:
- Compile-time (no runtime VDOM).
- 작은 bundle.
- Beautiful syntax.
- Smaller ecosystem.

React:
- 가장 큰 ecosystem.
- Compiler (modern).
- JSX (TS-friendly).

→ 다 좋음. Team 의 선호.

Vue 의 reactivity caveat

const obj = reactive({ count: 0 });

// ❌ Lost reactivity
const { count } = obj;
count++;  // 안 trigger.

// ✅ Use ref
const count = ref(0);
// 또는
import { toRefs } from 'vue';
const { count } = toRefs(obj);

→ Destructure 가 lose reactivity.

Svelte 5 의 reactive store

<script>
  // global state file (state.svelte.ts)
  export const userStore = $state({ name: '' });
  
  // 사용
  $effect(() => {
    console.log(userStore.name);
  });
</script>

→ Global signal 식.

Vue v-model (two-way)

<input v-model='message' />
<!-- 동등 -->
<input :value='message' @input='message = $event.target.value' />

→ Two-way binding 가 native.

Vue Teleport (portal)

<Teleport to='body'>
  <div class='modal'>...</div>
</Teleport>

→ React Portal 비슷.

Suspense

<Suspense>
  <template #default>
    <AsyncComponent />
  </template>
  <template #fallback>
    <Loading />
  </template>
</Suspense>

Lifecycle (Vue)

import { onMounted, onUnmounted, onUpdated } from 'vue';

onMounted(() => { ... });
onUnmounted(() => { ... });
onUpdated(() => { ... });

Lifecycle (Svelte 5)

<script>
  import { onMount, onDestroy } from 'svelte';
  
  onMount(() => {
    return () => { /* cleanup */ };
  });
</script>

Production

Vue:
- Alibaba, Tencent (China).
- Nuxt site / blog.
- Enterprise admin.

Svelte:
- The New York Times.
- Apple Music (옛).
- Brave browser.

Migration from React

Vue:
- API 가 비슷 (composition).
- Template 다름.
- Pinia ≈ Zustand.
- Nuxt ≈ Next.

Svelte:
- 더 다름.
- 작은 bundle.
- 새 mental model.

→ Vue 가 React → migration 가 부드러움.

Performance

Svelte: 가장 빠름 (compile-time).
Vue 3: 빠름 (reactivity).
React + Compiler: 빠름.

→ 매 framework 가 modern.

LLM 도움

Vue / Svelte 의 docs 가 LLM 에 baked.
- Component 작성 OK.
- 작은 ecosystem 의 niche library 가 약.

→ React 보다 정확도 약간 ↓.

🤔 의사결정 기준

상황 추천
큰 ecosystem React
작은 bundle Svelte
HTML-friendly Vue
China market Vue
Beautiful code Svelte
Modern team 매 다 OK

안티패턴

  • Vue reactive destructure: lost.
  • Svelte 4 → 5 mix runes: 깨짐.
  • Library 가 React-only: lock-in.
  • Mixed framework: complexity.

🤖 LLM 활용 힌트

  • Vue 3 composition API 가 modern.
  • Svelte 5 runes = signal-based.
  • Pinia / Nuxt / SvelteKit = ecosystem.
  • React + Compiler 와 수렴.

🔗 관련 문서