Pinia 兩種寫法全解析:Options Store vs Setup Store(含實踐與場景對比)

目標:把 Pinia 的兩種寫法講透,寫明“怎么寫、怎么用、怎么選、各自優缺點與典型場景”。全文配完整代碼與注意事項,可直接當團隊規范參考。


一、背景與準備

  • 適用版本:Vue 3 + Pinia 2.x
  • 安裝與初始化:
# 安裝
npm i pinia# main.ts/main.js
import { createApp } from 'vue'
import { createPinia } from 'pinia'
import App from './App.vue'const app = createApp(App)
app.use(createPinia())
app.mount('#app')

Pinia 提供兩種定義 Store 的方式:

  • Options Store(配置式):寫法類似 Vuex,結構清晰,學習成本低。
  • Setup Store(組合式):寫法與 Composition API 一致,靈活可復用,能直接使用 refcomputedwatch、自定義 composable。

下面分別實現 同一個業務:計數器 + 異步拉取用戶信息,用兩種寫法各做一遍,再對比差異與使用場景。


二、Options Store(配置式)

2.1 定義

// stores/counter.ts
import { defineStore } from 'pinia'export const useCounterStore = defineStore('counter', {// 1) state:必須是函數,返回對象;可被 DevTools 追蹤、可序列化state: () => ({count: 0,user: null as null | { id: number; name: string }}),// 2) getters:類似計算屬性,支持緩存與依賴追蹤getters: {double: (state) => state.count * 2,welcome(state) {return state.user ? `Hi, ${state.user.name}` : 'Guest'}},// 3) actions:業務方法,支持異步;這里的 this 指向 store 實例actions: {increment() {this.count++},reset() {this.$reset()},async fetchUser() {// 模擬請求await new Promise((r) => setTimeout(r, 400))this.user = { id: 1, name: 'Tom' }}}
})

注意:在 actions 里不要用箭頭函數,否則 this 不指向 store;如果必須用箭頭函數,改為顯式引用 useCounterStore() 返回的實例。

2.2 組件中使用

<script setup lang="ts">
import { storeToRefs } from 'pinia'
import { useCounterStore } from '@/stores/counter'const counter = useCounterStore()
// 解構 state/getters 請用 storeToRefs,保持解構后的值仍具備響應性
const { count, double, welcome, user } = storeToRefs(counter)function add() {counter.increment()
}function load() {counter.fetchUser()
}
</script><template><div class="card"><p>count: {{ count }}</p><p>double: {{ double }}</p><p>{{ welcome }}</p><button @click="add">+1</button><button @click="load">拉取用戶</button></div>
</template>

2.3 進階用法

const counter = useCounterStore()// 批量更新(避免多次觸發)
counter.$patch({ count: counter.count + 2, user: { id: 2, name: 'Jerry' } })// 監聽狀態變化(持久化/日志)
const unsubscribe = counter.$subscribe((mutation, state) => {// mutation.type: 'direct' | 'patch object' | 'patch function'// 可在這里做本地存儲localStorage.setItem('counter', JSON.stringify(state))
})// 監聽 action 調用鏈
counter.$onAction(({ name, args, onAfter, onError }) => {console.time(name)onAfter(() => console.timeEnd(name))onError((e) => console.error('[action error]', name, e))
})

優點小結(Options Store)

  • 結構化:state/getters/actions 職責清晰、易讀易管控。
  • 遷移友好:從 Vuex 遷移幾乎零心智負擔。
  • 可序列化:state 天生適合被 DevTools/SSR 序列化與持久化插件處理。
  • this 能直達 getters/state,寫法直觀(注意不要箭頭函數)。

注意點

  • 需要通過 this 訪問 store(對 TS “this” 的類型提示依賴更強)。
  • getters 中不要產生副作用;復雜邏輯建議放到 actions

三、Setup Store(組合式)

3.1 定義

// stores/counter-setup.ts
import { defineStore } from 'pinia'
import { ref, computed, watch } from 'vue'export const useCounterSetup = defineStore('counter-setup', () => {// 1) 直接用 Composition APIconst count = ref(0)const user = ref<null | { id: number; name: string }>(null)const double = computed(() => count.value * 2)const welcome = computed(() => (user.value ? `Hi, ${user.value.name}` : 'Guest'))// 2) 方法就寫普通函數(無 this,更易測試/復用)function increment() {count.value++}function reset() {count.value = 0user.value = null}async function fetchUser() {await new Promise((r) => setTimeout(r, 400))user.value = { id: 1, name: 'Tom' }}// 3) 可直接使用 watch 等組合式能力watch(count, (v) => {if (v > 10) console.log('count 很大了')})// 4) 返回對外可用的成員return { count, user, double, welcome, increment, reset, fetchUser }
})

3.2 組件中使用

<script setup lang="ts">
import { storeToRefs } from 'pinia'
import { useCounterSetup } from '@/stores/counter-setup'const store = useCounterSetup()
const { count, double, welcome, user } = storeToRefs(store)function add() {store.increment()
}
</script><template><div class="card"><p>count: {{ count }}</p><p>double: {{ double }}</p><p>{{ welcome }}</p><button @click="add">+1</button><button @click="store.fetchUser()">拉取用戶</button><button @click="store.reset()">重置</button></div>
</template>

3.3 進階用法(復用邏輯 & 外部 composable)

// composables/usePersist.ts(示例)
import { watch } from 'vue'
export function usePersist<T extends object>(key: string, state: T) {watch(() => state,(val) => localStorage.setItem(key, JSON.stringify(val)),{ deep: true })
}// stores/profile.ts - 在 Setup Store 里直接用組合函數
import { defineStore } from 'pinia'
import { reactive, computed } from 'vue'
import { usePersist } from '@/composables/usePersist'export const useProfile = defineStore('profile', () => {const form = reactive({ name: '', age: 0 })const valid = computed(() => form.name.length > 0 && form.age > 0)usePersist('profile', form)return { form, valid }
})

優點小結(Setup Store)

  • 靈活:原生 Composition API 能力全開(ref/computed/watch/async/自定義 composable)。
  • 可復用:把復雜業務拆到多個 composable,再組合進 store。
  • 更易測試:普通函數、無 this 語義,單元測試與類型推斷更直觀。

注意點

  • 返回的成員必須顯式 return,未返回的屬性對外不可見。
  • 非可序列化的值(如函數、Map、類實例)放入 state 時需考慮 SSR/持久化的影響。

四、兩種寫法如何選?(場景對比)

維度Options Store(配置式)Setup Store(組合式)
上手成本低,結構固定,接近 Vuex中等,需要熟悉 Composition API
代碼組織三段式清晰:state/getters/actions任意組織,更靈活,也更考驗規范
邏輯復用依賴抽出到獨立函數/插件直接用 composable,自然拼裝
this 使用actions 里有 this,直達 state/getters無 this,純函數,易測試
TypeScript對 this 的類型推斷要注意類型自然跟隨 ref/reactive
DevTools/序列化天然友好(state 可序列化)取決于返回的成員是否可序列化
典型場景業務中小、邏輯清晰、團隊從 Vuex 遷移中大型、復合邏輯、強復用/抽象需求

選擇建議

  • 團隊以簡單業務/快速落地/從 Vuex 遷移為主 → 優先 Options Store
  • 團隊重組合式、強調復用與抽象,或需要在 store 內使用 watch / 自定義 composable → 選擇 Setup Store
  • 實際項目中可以混用:簡單模塊用 Options,復雜域(如表單域、編輯器域)用 Setup。

五、最佳實踐清單

  1. 永遠用 storeToRefs 解構:保持解構后仍具備響應性。
  2. 批量更新用 $patch:一次性修改多個字段,減少觸發次數。
  3. 持久化:使用插件 @pinia/plugin-persistedstate 或自寫 $subscribe 落地。
  4. SSR:每次請求都要創建新的 pinia 實例;避免向 state 放入不可序列化的“大對象”。
  5. 跨 Store 調用:在 action 內部調用另一個 store,按需引入,避免循環依賴。
  6. 命名規范stores/模塊名.ts,導出 useXxxStore/useXxxSetup 等有語義的命名。

六、從 Vuex 遷移到 Pinia(速查)

VuexPinia(Options)
statestate() { return { … } }
gettersgetters: { double: (s)=>s.count*2 }
mutationsactions(同步/異步都放 actions)
actions仍然是 actions
mapState/mapGetters直接 storeToRefs(useStore()) 解構

遷移時最常見問題:丟失響應性。記得使用 storeToRefs,或在模板中直接用 store.count 不解構。


七、常見坑位與排查

  • 解構丟響應性const { count } = useStore() ? → const { count } = storeToRefs(useStore()) ?
  • actions 用了箭頭函數導致 this 丟失(Options):改普通函數或顯式引用 store。
  • 在 getters 里寫副作用:應移到 action 或 watch。
  • 循環依賴:跨 store 調用時注意 import 時機,可在 action 內部按需調用另一個 store。
  • SSR 水合失敗:state 內含不可序列化值;或客戶端初始 state 與服務端不一致。

八、結語

Options Store 強在“結構化與可維護”,Setup Store 勝在“靈活與復用”。
選型的關鍵不是“誰更先進”,而是“當前問題需要哪種力量”。理解兩種寫法的邊界與優勢,團隊協作會更順手、代碼也更可持續。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/98136.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/98136.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/98136.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

setup函數相關【3】

目錄1.setup函數&#xff1a;1.概述&#xff1a;2.案例分析&#xff1a;2.setup函數的優化&#xff1a;&#xff08;setup語法糖&#xff09;優化1&#xff1a;優化2&#xff1a;安裝插件&#xff1a;安裝指令&#xff1a;只對當前項目安裝配置vite.config.ts&#xff1a;代碼編…

如何通過AI進行數據資產梳理

最終產出 數據資產清單 包含所有數據資產的詳細目錄,列出數據集名稱、描述、所有者、格式、存儲位置和元數據。 用途:幫助政府部門清晰了解數據資產分布和狀態。 數據質量報告 數據質量評估結果,記錄準確性、完整性、一致性等問題及改進建議,基于政府認可的數據質量框架(如…

【傳奇開心果系列】Flet框架結合pillow實現的英文文字倒映特效自定義模板特色和實現原理深度解析

Flet框架結合pillow實現的英文文字倒映特效自定義模板特色和實現原理深度解析 一、效果展示截圖 二、使用場景 三、特色說明 四、概括說明 五、依賴文件列表 六、安裝依賴命令 七、 項目結構建議 八、注意事項 九、Flet 文字倒影效果實現原理分析 (一)組件結構與功能 1. 圖像…

2025最新深度學習面試必問100題--理論+框架+原理+實踐 (下篇)

2025最新深度學習面試必問100題–理論框架原理實踐 (下篇) 在上篇中&#xff0c;我們已經深入探討了機器學習基礎、CNN、RNN及其變體&#xff0c;以及模型優化的核心技巧。 在下篇中&#xff0c;我們將把目光投向更遠方&#xff0c;聚焦于當今AI領域最炙手可熱的前沿。我們將深…

原子工程用AC6編譯不過問題

…\Output\atk_h750.axf: Error: L6636E: Pre-processor step failed for ‘…\User\SCRIPT\qspi_code.scf.scf’修改前&#xff1a; #! armcc -E ;#! armclang -E --targetarm-arm-none-eabi -mcpucortex-m7 -xc /* 使用說明 ! armclang -E --targetarm-arm-none-eabi -mcpuco…

Python有哪些經典的常用庫?(第一期)

目錄 1、NumPy (數值計算基礎庫) 核心特點&#xff1a; 應用場景&#xff1a; 代碼示例&#xff1a; 2、Pandas (數據分析處理庫) 應用場景&#xff1a; 代碼示例&#xff1a; 3、Scikit-learn (機器學習庫) 核心特點&#xff1a; 應用場景&#xff1a; 代碼示例&am…

現代 C++ 高性能程序驅動器架構

&#x1f9e0; 現代 C 高性能程序驅動器架構M/PA&#xff08;多進程&#xff09;是隔離的“孤島”&#xff0c;M/TA&#xff08;多線程&#xff09;是共享的“戰場”&#xff0c;EDSM&#xff08;事件驅動&#xff09;是高效的“反應堆”&#xff0c;MDSM&#xff08;消息驅動&…

投資儲能項目能賺多少錢?小程序幫你測算

為解決電網負荷平衡、提升新能源消納等問題&#xff0c;儲能項目的投資開發越來越多。那么&#xff0c;投資儲能項目到底能賺多少錢&#xff1f;適不適合投資&#xff1f;用“綠蟲零碳助手”3秒鐘精準測算。操作只需四步&#xff0c;簡單易懂&#xff1a;1.快速登錄&#xff1a…

Mac 能夠連Wife,但是不能上網問題解決

請按照以下步驟從最簡單、最可能的原因開始嘗試&#xff1a; 第一步&#xff1a;基礎快速排查 這些步驟能解決大部分臨時性的小故障。 重啟設備&#xff1a;關閉您的 Mac 和路由器&#xff0c;等待一分鐘后再重新打開。這是解決網絡問題最有效的“萬能藥”。檢查其他設備&am…

基于SpringBoot的旅游管理系統的設計與實現(代碼+數據庫+LW)

摘要 本文闡述了一款基于SpringBoot框架的旅游管理系統設計與實現。該系統整合了用戶信息管理、旅游資源展示、訂單處理流程及安全保障機制等核心功能&#xff0c;專為提升旅游行業的服務質量和運營效率而設計。 系統采用前后端分離架構&#xff0c;前端界面設計注重跨設備兼…

Springboot樂家流浪貓管理系統16lxw(程序+源碼+數據庫+調試部署+開發環境)帶論文文檔1萬字以上,文末可獲取,系統界面在最后面。

系統程序文件列表項目功能&#xff1a;領養人,流浪貓,領養申請開題報告內容基于Spring Boot的樂家流浪貓管理系統開題報告一、研究背景與意義隨著城市化進程加速和人口增長&#xff0c;流浪貓問題已成為全球性社會挑戰。據統計&#xff0c;全球每年約有1.5億只無家可歸的寵物&a…

函數定義跳轉之代碼跳轉

相信大家在開發的過程中都有用到函數定義跳轉的功能&#xff0c;在 IDE 中&#xff0c;如果在函數調用的地方停留光標&#xff0c;可能會提示對應的函數定義&#xff0c;在 GitHub 中也是如此&#xff0c;對于一些倉庫來說&#xff0c;我們可以直接查看對應的函數定義了&#x…

探討Xsens在人形機器人研發中的四個核心應用

探索Xsens動作捕捉如何改變人形機器人研發——使機器人能夠從人類運動中學習、更直觀地協作并彌合模擬與現實世界之間的差距。人形機器人技術是當今世界最令人興奮且最復雜的前沿領域之一。研究人員不僅致力于開發能夠像人類一樣行走和行動的機器人&#xff0c;還致力于開發能夠…

C語言高級編程:一文讀懂數據結構的四大邏輯與兩大存儲

各類資料學習下載合集 ??https://pan.quark.cn/s/8c91ccb5a474? 作為一名程序員,我們每天都在與“數據”打交道。但你是否想過,這些數據在計算機中是如何被“整理”和“安放”的?為什么有些操作快如閃電,而有些則慢如蝸牛? 答案就藏在數據結構之中。 如果說算法是…

MySQL問題4

MySQL中varchar和char的區別 在 MySQL 中&#xff0c;VARCHAR 和 CHAR 都是用于存儲字符串類型的字段&#xff0c;但它們在存儲方式、性能、適用場景等方面存在明顯區別&#xff1a;1. 存儲方式類型說明CHAR(n)定長字符串&#xff0c;始終占用固定 n 個字符空間。不足的會自動在…

Web3 出海香港 101 |BuildSpace AMA 第一期活動高亮觀點回顧

香港政府在 2022-2023 年之間已經開始布局 Web3&#xff0c;由香港政府全資擁有的數碼港也進行了持續兩年多的深耕。目前數碼港已有接近 300 家企業入駐于此&#xff0c;包括 Animoca Brands、HashKey Group、CertiK 等行業知名獨角獸公司。此外&#xff0c;如 Cobo、OneKey、D…

LTE CA和NR CA的區別和聯系

LTE CA&#xff08;Carrier Aggregation&#xff09;和NR CA&#xff08;New Radio Carrier Aggregation&#xff09;都是載波聚合技術&#xff0c;它們的核心目標都是通過組合多個頻段的帶寬來提高數據傳輸速率&#xff0c;增強無線網絡的吞吐量。盡管它們的功能相似&#xff…

VBA 中的 Excel 工作表函數

一、引言 在使用VBA進行Excel自動化處理時&#xff0c;我們經常需要調用Excel內置的工作表函數來完成復雜的計算或數據處理任務。然而&#xff0c;很多VBA初學者并不清楚如何正確地在VBA中調用這些函數&#xff0c;甚至重復造輪子。本文將從基礎到進階&#xff0c;系統介紹如何…

老年公寓管理系統設計與實現(代碼+數據庫+LW)

摘要 隨著老齡化社會的不斷發展&#xff0c;老年人群體的生活質量和管理需求逐漸引起社會的廣泛關注。為了提高老年公寓的管理效率與服務質量&#xff0c;開發了一種基于SpringBoot框架的老年公寓管理系統。該系統充分利用了SpringBoot框架的快速開發優勢&#xff0c;結合現代…

綠算技術與清智圖靈簽署戰略合作協議

近日&#xff0c;廣東省綠算技術有限公司&#xff08;以下簡稱“綠算技術”&#xff09;與北京清智圖靈科技有限公司&#xff08;以下簡稱“清智圖靈”&#xff09;正式簽署戰略合作框架協議。雙方將圍繞通用并行計算、高端算力解決方案等領域展開深度合作&#xff0c;共同推動…