跨越元件的溝通橋樑 (useState)
在我們的應用程式中,常常需要讓不同的元件共享同一份資料。例如:
- 使用者的登入狀態
- 網站的主題模式(淺色/深色)
- 購物車裡的商品
今天,我們就來學習 Nuxt 是如何安全地處理這種「共享狀態 (Shared State)」的。
1. 為什麼不能隨便共享?— 伺服器上的危險
在 Nuxt 這種全端框架中,如果我們用一般的方法建立一個全域變數來共享狀態,會發生一個嚴重的問題:
在伺服器上,所有同時訪問網站的使用者,都會共用到同一個變數!這意味著 A 使用者的資料可能會洩漏給 B 使用者,這絕對是我們不想看到的。
2. Nuxt 的安全解法:useState
為了解決這個問題,Nuxt 提供了一個內建的 composable:useState
。
您可以把它想像成是為每個使用者在伺服器上準備的一個專屬保險箱。它確保了每個人的資料都是獨立的,不會互相干擾,並且在頁面渲染後,會安全地將「保險箱」裡的資料(透過 Payload)交到使用者手上。
useState
的使用方法很簡單,它需要兩個參數:
一個唯一的 Key (字串):保險箱的標籤,用來識別是哪一個狀態。
一個初始值的函式:當這個保險箱第一次被建立時,裡面要放什麼。
<script setup>
// 建立或取得一個名為 'counter' 的狀態,如果它不存在,就將初始值設為 0
const counter = useState('counter', () => 0);
</script>
<template>
<div>
<p>計數器: {{ counter }}</p>
<button @click="counter++">+</button>
<button @click="counter--">-</button>
</div>
</template>
現在,您可以在任何其他元件中,用同樣的 Key 來取得這個狀態:
// 在另一個元件中
const counter = useState('counter'); // Nuxt 會知道這是同一個保險箱,直接把值拿給你
3. 最佳實踐:建立自己的狀態 Composables
為了讓程式碼更有組織,也方便重複使用,最好的方法是把 useState
包裝在一個自己的 composable 函式裡。
在 composables/ 資料夾中建立一個檔案,例如 states.ts
在檔案中定義您的共享狀態
// composables/states.ts
export const useCounter = () => useState('counter', () => 0);
export const useTheme = () => useState('theme', () => 'light');
現在,在任何元件中,您都可以像這樣直觀地使用它
<script setup>
const counter = useCounter();
const theme = useTheme();
</script>
這種做法讓您的狀態管理變得非常乾淨、可追蹤且易於維護。
今日總結
今天我們學會了 Nuxt 內建的 useState,它是處理跨元件共享狀態最基本、也最重要的方法。
它解決了在伺服器上共享狀態的安全性問題。
透過唯一的 Key 來存取同一個狀態。
最佳實踐是將它包裝成一個 composable。
預告:useState 很適合處理簡單的共享狀態。但如果我們的狀態邏輯變得複雜,需要更嚴謹的結構(例如,購物車不只可以新增商品,還要能計算總價),那該怎麼辦呢?明天,我們將來認識 Vue 生態系官方推薦的狀態管理庫:Pinia。