專業的狀態管理大師 (Pinia)
1. 為什麼需要 Pinia?
useState
很好用,但當您的應用程式變大,狀態邏輯越來越複雜時,您可能會遇到一些挑戰:
邏輯分散
修改狀態的程式碼可能散落在各個元件中,難以追蹤。
缺乏結構
沒有統一的地方來定義「可以對這個狀態做哪些操作」。
難以除錯
當狀態出錯時,很難知道是哪個元件把它改壞的。
Pinia 就是為了解決這些問題而生的。您可以把它想像成是為您的共享狀態,建立一個專門的管理部門。
2. Pinia 的核心概念:Store
在 Pinia 中,每一個「共享狀態」都會被定義在一個稱為 Store 的檔案裡。這個 Store 就像一個部門,它清楚地劃分了三種職責:
state:部門的資料庫
這是一個函式,用來存放這個部門最核心的資料。就像 useState
的初始值。
actions:部門的行動方案
這是一個物件,用來定義「可以對資料做哪些事」。所有修改 state
的非同步或複雜同步邏輯都應該寫在這裡。例如,從 API 獲取使用者資料並更新 state
。
getters:部門的報告產生器
這是一個物件,用來定義如何從 state
中衍生出新的資料,就像 Vue 的 computed
。例如,從購物車的商品清單中,計算出總金額。
3. 在 Nuxt 中使用 Pinia
得益於 Nuxt 強大的模組生態系,整合 Pinia 變得輕而易舉。
第一步:安裝模組
打開終端機,執行 Nuxt 提供的指令:
npx nuxt module add pinia
這個指令會幫您安裝好所有需要的套件,並在 nuxt.config.ts 中自動設定好模組。
第二步:建立您的第一個 Store
在 stores/ 資料夾中建立一個檔案,例如 user.ts。
// stores/user.ts
import { defineStore } from 'pinia';
// defineStore('唯一的 Store ID', { ...設定 })
export const useUserStore = defineStore('user', {
// 1. 資料庫 (State)
state: () => ({
isLoggedIn: false,
name: '訪客'
}),
// 2. 報告產生器 (Getters)
getters: {
welcomeMessage: (state) => `你好,${state.name}`
},
// 3. 行動方案 (Actions)
actions: {
login(username) {
this.isLoggedIn = true;
this.name = username;
},
logout() {
this.isLoggedIn = false;
this.name = '訪客';
}
}
})
第三步:在元件中使用 Store
現在,在任何元件中,您都可以像呼叫 composable 一樣,來取得並操作這個 Store。
<script setup>
import { useUserStore } from '~/stores/user';
// 取得 user Store 的實體
const userStore = useUserStore();
</script>
<template>
<div>
<p>{{ userStore.welcomeMessage }}</p>
<div v-if="userStore.isLoggedIn">
<button @click="userStore.logout()">登出</button>
</div>
<div v-else>
<button @click="userStore.login('Re:Human')">登入</button>
</div>
</div>
</template>
今日總結
今天我們學會了使用 Pinia 來建立一個結構清晰、權責分明的狀態管理系統。
Store 是 Pinia 的核心,它將 state、getters 和 actions 整合在一起。
State
存放資料。
Getters
衍生資料。
Actions
修改資料。
當您的應用程式規模擴大時,Pinia 將是您管理複雜狀態時最得力的助手!