核心修練
CoreState
狀態管理
在 SSR 框架中,狀態管理比純 SPA 複雜。Nuxt 提供了 useState 組合式函數,解決了伺服器端與客戶端狀態同步的難題。
為什麼需要 useState?
你可能會問:「為什麼不能直接用 Vue 的 ref?」
答案在於 **SSR (伺服器端渲染)** 的運作機制。
使用 ref 的風險
如果在 setup() 外部定義全域 ref, 這個變數會在 Node.js 伺服器記憶體中被所有使用者的請求共享。
// 危險!所有使用者會看到同一個 counter
const globalCounter = ref(0)
const globalCounter = ref(0)
useState 的保護
useState 會在伺服器端為每個請求建立獨立的狀態實例, 並自動將資料序列化 (Serialize) 傳送到客戶端,完成水合 (Hydration)。
// 安全。每個請求都有獨立的 counter
const counter = useState('count', () => 0)
const counter = useState('count', () => 0)
實驗室:Local vs Shared State
試著操作下方的按鈕。你會發現 ref (Local) 只會影響單一元件, 而 useState (Shared) 則會同步更新所有使用該 Key 的元件。
Component A
Local State (ref)Isolated
0
Shared State (useState)
0
Component B
Local State (ref)Isolated
0
Shared State (useState)
0
Auto-synced
基本用法
useState 接受兩個參數:一個唯一的 key (字串) 和一個初始化函數。
app.vue
<script setup>
// 'counter' 是全域唯一的 key
const count = useState('counter', () => 0)
const increment = () => {
count.value++
}
</script>
<template>
<button @click='increment'>
Count: {{ count }}
</button>
</template>參數說明
- 1Key (String)
用於識別狀態的唯一鍵值。如果在不同元件使用相同的 key,它們會共享同一個狀態。
- 2Init (Function)
初始化函數。只會在狀態尚未存在時執行一次。
自動 Key 生成
如果你在元件的 script setup 頂層使用,Nuxt 可以自動為你生成 key,但在 Composables 中建議手動指定。
進階:Pinia
雖然 useState 足夠應付簡單場景,但當應用程式變得複雜時, 官方推薦使用 Pinia。
- DevTools 支援 (時光旅行除錯)
- 熱模組替換 (HMR)
- 更完整的 TypeScript 型別推斷