为什么选择 Svelte
写了几年前后端分离的项目,常用的前端框架是 Vue 和 React。它们都是作为 SPA 设计的框架,没有 SEO 优化,初次加载比较慢。虽然有 Nuxt 和 Next 等框架来解决这个问题,但仍有些笨重。如果是小型项目,还是希望能有更轻量的框架。
Svelte 就是满足这方面需求的框架,设计上就考虑了 SEO 优化,并且很适合小型项目。
Svelte 的特点
- 写法更传统:上手难度小,更接近原生 HTML/CSS/JS
- 没有虚拟 DOM:没有运行时开销,性能更好
- 生成代码更小:编译时优化,生成的包体积更小,更适合小型项目
SvelteKit
SvelteKit 是 Svelte 团队推出的现代 Web 框架,包含了路由、服务端渲染、静态站点生成等功能。
创建项目
$ npx sv create
Need to install the following packages:
sv@0.8.10
Ok to proceed? (y)
┌ Welcome to the Svelte CLI! (v0.8.10)
│
◇ Where would you like your project to be created?
│ ./
│
◇ Which template would you like?
│ SvelteKit minimal
│
◇ Add type checking with TypeScript?
│ Yes, using TypeScript syntax
│
◆ Project created
│
◇ What would you like to add to your project? (use arrow keys / space bar)
│ tailwindcss
│
◇ Which plugins would you like to add?
│ typography
│
◆ Successfully setup add-ons
│
◇ Which package manager do you want to install dependencies with?
│ npm
│
◆ Successfully installed dependencies
│
◇ Project next steps ─────────────────────────────────────────────────────╮
│ │
│ 1: git init && git add -A && git commit -m "Initial commit" (optional) │
│ 2: npm run dev -- --open │
│ │
│ To close the dev server, hit Ctrl-C │
│ │
│ Stuck? Visit us at https://svelte.dev/chat │
│ │
├──────────────────────────────────────────────────────────────────────────╯
│
└ You're all set!
启动开发环境:
npm run dev -- --host
加了 --host 允许从别的机器访问。需要加 -- 用来将后面的参数传入 Vite。
编写内容
首页内容在 src/routes/+page.svelte 文件中。
组件
属性
在页面添加 script 代码块,并设定变量,即可在 HTML 中使用:
<script lang="ts">
let name = "Svelte";
</script>
<h1>Hello {name}!</h1>
动态属性
<script>
let src = '/tutorial/image.gif';
</script>
<img src={src} />
<img {src} />
作为属性时,不需要加引号。如果属性的名称和值同名,可以简化为 {src}。
样式
在页面添加 style 代码块,设定样式。样式自动作用于当前组件:
<style>
p {
font-size: 20px;
}
</style>
组件嵌套
在组件中 import 另一个组件,并在 HTML 中使用:
<script lang="ts">
import Nested from './Nested.svelte';
</script>
<p>This is a component</p>
<Nested />
HTML 渲染
默认情况下,Svelte 会将 HTML 转义,以防止 XSS 攻击。如果需要渲染 HTML,可以使用 {@html} 指令:
<p>{@html string}</p>
响应式状态
Svelte 使用 $state 创建响应式变量。当这些变量改变时,Svelte 自动更新 DOM。
<script lang="ts">
let count = $state(0);
function increment() {
count += 1;
}
</script>
<button onclick={increment}>
Clicked {count}
{count === 1 ? 'time' : 'times'}
</button>
也可以用于数组:
<script lang="ts">
let numbers = $state([0, 1, 2, 3, 4]);
</script>
派生状态
$derived 用于计算派生状态,当原始状态改变时会自动重新计算:
<script lang="ts">
let numbers = $state([1, 2, 3, 4]);
let total = $derived(numbers.reduce((t, n) => t + n, 0));
</script>
状态追踪
使用 $inspect() 输出状态变化,$state.snapshot() 获取当前快照:
<script lang="ts">
let numbers = $state([1, 2, 3, 4]);
let total = $derived(numbers.reduce((t, n) => t + n, 0));
function addNumber() {
numbers.push(numbers.length + 1);
console.log($state.snapshot(numbers));
}
$inspect(numbers);
</script>
Props
Props 用于从父组件向子组件传递数据,使用 $props 接收:
<!-- Child.svelte -->
<script lang="ts">
let { message = 'default' } = $props();
</script>
<p>{message}</p>
父组件中使用子组件并传递 props:
<!-- Parent.svelte -->
<script lang="ts">
import Child from './Child.svelte';
</script>
<Child message="Hello from parent" />
事件
子组件通过事件将数据传递给父组件,使用 createEventDispatcher 或直接用 onclick 等事件处理:
<!-- Child.svelte -->
<script lang="ts">
let { onchange } = $props();
</script>
<button onclick={() => onchange?.(123)}>Send message</button>
父组件监听事件:
<!-- Parent.svelte -->
<script lang="ts">
import Child from './Child.svelte';
function handleChange(value) {
console.log(value);
}
</script>
<Child onchange={handleChange} />
双向绑定
使用 bind: 指令实现双向绑定:
<script lang="ts">
let name = $state('');
</script>
<input bind:value={name} />
<p>Hello {name}</p>
路由
SvelteKit 使用文件系统路由。在 src/routes/ 目录下创建文件或文件夹:
+page.svelte:页面组件+layout.svelte:布局组件,适用于该目录及子目录[id]:动态路由参数,如/posts/[id]
获取路由参数
<script lang="ts">
import { page } from '$app/stores';
$: id = $page.params.id;
</script>
<p>Post ID: {id}</p>
常用工具
响应式声明
使用 $: 声明响应式代码,当依赖变化时自动执行:
<script lang="ts">
let count = $state(0);
$: doubled = count * 2;
$: if (count > 10) console.log('count is over 10');
</script>
生命周期
常用的生命周期:
import { onMount, onDestroy } from 'svelte';
onMount(() => {
console.log('组件挂载');
return () => {
console.log('清理');
};
});
onDestroy(() => {
console.log('组件卸载');
});
总结
Svelte 以其简洁的语法、出色的性能和小的包体积,成为小型项目和追求性能的团队的好选择。如果你来自 Vue 或 React 背景,转向 Svelte 会有新的体验和启发。
最后修改于 2025-06-15