Skip to content

Svelte 与 Vue3 语法对比

1. 组件结构对比

Vue3 组件

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

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

const increment = () => {
  count.value++
}
</script>

<template>
  <div>
    <p>Count: {{ count }}</p>
    <p>Double: {{ doubleCount }}</p>
    <button @click="increment">+1</button>
  </div>
</template>

<style scoped>
div {
  color: blue;
}
</style>

Svelte 组件

svelte
<script lang="ts">
  let count = 0
  $: doubleCount = count * 2

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

<div>
  <p>Count: {count}</p>
  <p>Double: {doubleCount}</p>
  <button on:click={increment}>+1</button>
</div>

<style>
  div {
    color: blue;
  }
</style>

2. 主要语法差异

2.1 响应式声明

  • Vue3: 使用 refreactive 等 API
typescript
const count = ref(0)
const state = reactive({ name: 'John' })
  • Svelte: 直接声明变量,使用 $: 声明响应式
typescript
let count = 0
$: doubled = count * 2

2.2 事件处理

  • Vue3: 使用 @v-on 指令
vue
<button @click="handleClick">Click</button>
  • Svelte: 使用 on: 前缀
svelte
<button on:click={handleClick}>Click</button>

2.3 条件渲染

  • Vue3: 使用 v-ifv-else 指令
vue
<div v-if="condition">Content</div>
<div v-else>Else Content</div>
  • Svelte: 使用 {#if}
svelte
{#if condition}
  <div>Content</div>
{:else}
  <div>Else Content</div>
{/if}

2.4 列表渲染

  • Vue3: 使用 v-for 指令
vue
<ul>
  <li v-for="item in items" :key="item.id">
    {{ item.name }}
  </li>
</ul>
  • Svelte: 使用 {#each}
svelte
<ul>
  {#each items as item (item.id)}
    <li>{item.name}</li>
  {/each}
</ul>

3. 实用 Svelte 示例

3.1 表单处理

svelte
<script lang="ts">
  let name = ''
  let email = ''
  let submitted = false

  function handleSubmit() {
    submitted = true
    // 处理表单提交
  }
</script>

<form on:submit|preventDefault={handleSubmit}>
  <input 
    type="text" 
    bind:value={name} 
    placeholder="Your name"
  />
  <input 
    type="email" 
    bind:value={email} 
    placeholder="Your email"
  />
  <button type="submit">Submit</button>
</form>

{#if submitted}
  <p>Thanks for submitting, {name}!</p>
{/if}

3.2 异步数据获取

svelte
<script lang="ts">
  import { onMount } from 'svelte'
  
  let posts = []
  let loading = true
  let error = null

  onMount(async () => {
    try {
      const response = await fetch('https://api.example.com/posts')
      posts = await response.json()
    } catch (e) {
      error = e.message
    } finally {
      loading = false
    }
  })
</script>

{#if loading}
  <p>Loading...</p>
{:else if error}
  <p class="error">{error}</p>
{:else}
  {#each posts as post}
    <article>
      <h2>{post.title}</h2>
      <p>{post.body}</p>
    </article>
  {/each}
{/if}

3.3 组件通信

svelte
<!-- Parent.svelte -->
<script lang="ts">
  import Child from './Child.svelte'
  
  let message = 'Hello from parent'
  function handleMessage(event: CustomEvent) {
    console.log(event.detail)
  }
</script>

<Child 
  message={message} 
  on:message={handleMessage}
/>

<!-- Child.svelte -->
<script lang="ts">
  import { createEventDispatcher } from 'svelte'
  
  export let message: string
  const dispatch = createEventDispatcher()
  
  function sendMessage() {
    dispatch('message', { text: 'Hello from child' })
  }
</script>

<div>
  <p>{message}</p>
  <button on:click={sendMessage}>Send Message</button>
</div>

4. 总结

Svelte 相比 Vue3 的主要优势:

  1. 更简洁的语法,减少样板代码
  2. 更直观的响应式系统
  3. 更小的运行时体积
  4. 更快的编译速度

Vue3 相比 Svelte 的主要优势:

  1. 更成熟的生态系统
  2. 更多的企业级应用案例
  3. 更丰富的社区资源
  4. 更完善的工具链支持