Svelte 3 在 2019 年發佈後引發了不小的關注。它的核心主張是:框架應該在編譯時完成工作,而不是在運行時。這意味着 Svelte 沒有虛擬 DOM,沒有運行時框架代碼,生成的產物是原生 DOM 操作的 JavaScript。
和 React/Vue 的根本區別
React/Vue 的工作流程:
用户代碼 → 框架運行時(虛擬 DOM diff)→ DOM 更新
Svelte 的工作流程:
用户代碼 → 編譯器(生成高效的 DOM 操作代碼)→ 純 JS → DOM 更新
結果:Svelte 應用的 bundle 裏沒有框架運行時,Hello World 的 gzip 體積約 1.6KB。
基礎語法
Svelte 組件是 .svelte 文件,結構類似 Vue 單文件組件:
svelte
<!-- Counter.svelte -->
<script>
let count = 0;
function increment() {
count++;
}
// 響應式聲明:$: 開頭,依賴變化時自動重新計算
$: doubled = count * 2;
$: {
console.log(`count changed to ${count}`);
}
</script>
<button on:click={increment}>
點擊了 {count} 次(doubled: {doubled})
</button>
<style>
button {
/* 樣式自動 scoped,不會泄漏 */
background: #ff3e00;
color: white;
}
</style>
響應式系統
Svelte 的響應式基於賦值觸發,而不是 setter 或 Proxy:
svelte
<script>
let arr = [1, 2, 3];
let obj = { name: 'Alice' };
function addItem() {
arr = [...arr, arr.length + 1]; // ✅ 賦值觸發更新
// arr.push(4); // ❌ 不觸發更新(沒有賦值)
}
function updateName() {
obj.name = 'Bob'; // ✅ 對象屬性賦值也會觸發(Svelte 特殊處理)
}
</script>
Props 和事件
svelte
<!-- Child.svelte -->
<script>
export let name; // export 聲明 prop
export let age = 18; // 默認值
import { createEventDispatcher } from 'svelte';
const dispatch = createEventDispatcher();
function handleClick() {
dispatch('greet', { message: `Hello, ${name}!` });
}
</script>
<button on:click={handleClick}>問候 {name}</button>
<!-- Parent.svelte -->
<script>
import Child from './Child.svelte';
function handleGreet(event) {
alert(event.detail.message);
}
</script>
<Child name="Alice" age={25} on:greet={handleGreet} />
Store(狀態管理)
javascript
// stores.js
import { writable, derived } from "svelte/store";
export const count = writable(0);
export const doubled = derived(count, ($count) => $count * 2);
// 組件裏使用 $ 前綴自動訂閲和取消訂閲
svelte
<script>
import { count, doubled } from './stores.js';
</script>
<p>Count: {$count}, Doubled: {$doubled}</p>
<button on:click={() => $count++}>+1</button>
編譯後的代碼
Svelte 的響應式賦值 count++ 在編譯後變成:
javascript
// 編譯後(簡化)
function increment() {
$$invalidate(0, count++, count); // 直接標記需要更新
}
沒有虛擬 DOM diff,直接操作 DOM,性能基準測試中名列前茅。
適用場景
- 追求極致包體積(嵌入式、低端設備)
- 獨立小組件/Widget 嵌入非 SPA 頁面
- 快速原型開發(語法簡潔,上手快)
不太適合:超大型團隊項目(TypeScript 支持相比 Angular 較弱)、需要豐富生態(Angular Material、Ant Design 這類成熟 UI 庫目前 Svelte 版本較少)。
總結
Svelte 不是要取代 React 或 Vue,而是提供了一種不同的思路:把框架複雜度從運行時轉移到編譯時。哪怕你的主力框架不是 Svelte,理解它的設計思路也對你理解前端框架的本質很有幫助。