Pinia 實戰教學:掌握語法風格與響應式解構技巧
在 Vue 3 的開發世界中,Pinia 提供了極大的靈活性。無論您喜歡傳統的開發模式,還是追求 Composition API 的現代感,Pinia 都能滿足您。本文將帶您深入了解 Pinia 的兩種語法風格,以及在使用時必須注意的「響應式」細節。
Pinia 的兩種語法風格
Pinia 允許開發者根據習慣選擇 Option Store 或 Setup Store。
Option Store (選項式)
與 Vue 2 的架構相似,適合喜歡將資料 state、計算屬性 getters 與方法 actions 清晰拆分的開發者。
js
// stores/counter.js
import { defineStore } from "pinia";
export default defineStore("counter", {
// 儲存資料處,類似 data
state: () => {
return {
count: 0,
};
},
// 計算衍生狀態,類似 computed
getters: {
doubleCount: (state) => state.count * 2,
},
// 修改資料的方法,類似 methods
actions: {
increment() {
this.count++;
},
},
});Setup Store (組合式)
這是偏向 Composition API 的寫作方式,傳入一個函式並回傳需要暴露的屬性,結構更彈性。
js
// stores/counter.js
import { ref, computed } from "vue";
import { defineStore } from "pinia";
export default defineStore("counter", () => {
const count = ref(0); // 相當於 state
const doubleCount = computed(() => count.value * 2); // 相當於 getters
function increment() {
// 相當於 actions
count.value++;
}
return {
count,
doubleCount,
increment,
};
});快速對照表
ref()/reactive()→state。computed()→getters。function()→actions。
如何在元件中正確使用 Store?
定義完 Store 後,必須在元件中引入並呼叫,才能發揮作用。
vue
// components/Counter.vue
<script setup>
import useCounterStore from "@/stores/counter";
const counterStore = useCounterStore();
</script>
<template>
<div>
<p>計數器: {{ counterStore.count }}</p>
<p>雙倍計數: {{ counterStore.doubleCount }}</p>
<input @click="counterStore.increment" type="button" value="increment" />
</div>
</template>進階:避免解構導致的響應式失效
這是許多 Vue 開發者常遇到的陷阱:store 是一個用 reactive 包裝的物件。如果您直接對它進行解構(Destructuring),解構出來的資料會失去響應式特性,畫面將不會隨資料更新。
錯誤示範(會失去響應式)
js
const { count, doubleCount } = counterStore; // 這樣拿到的只是普通的數值,不會聯動更新正確做法:使用 storeToRefs()
為取出 store 中的屬性並保持其響應式,我們必須使用 Pinia 提供的 storeToRefs() 工具。若為 action 或非響應式的屬性,直接解構無妨。如下:
vue
// components/Counter.vue
<script setup>
import { storeToRefs } from "pinia";
import useCounterStore from "@/stores/counter";
const counterStore = useCounterStore();
const { count, doubleCount } = storeToRefs(counterStore);
const { increment } = counterStore;
</script>
<template>
<div>
<p>計數器: {{ count }}</p>
<p>雙倍計數: {{ doubleCount }}</p>
<input @click="increment" type="button" value="increment" />
</div>
</template>總結
掌握了 Option / Setup Store 的語法差異以及 storeToRefs 的使用時機,您已經避開了 Pinia 最常見的錯誤。選擇適合專案的寫法,能讓您的 Vue 3 狀態管理既優雅又強大。
