Pinia-使用筆記
簡介
- 在 Vue3 的 Composition API 推出後,官方推薦搭配使用的新工具
- 移除了 Vuex 的 mutations
- 對於 TypeScript 的支援度更高
- 檔案結構更為扁平化,根據狀態的類型分類儲存
- 支援 Server Side Rendering
核心概念
state
- 如同 data,定義狀態的地方
getter
- 如同 computed,state 的計算屬性
actions
- 如同 methods,改變 state 的方法,包含非同步操作
如何使用
- 以 Vue3 的 Composition API 寫法為例
- 在
main.ts
當中引入
import { createApp } from 'vue'import { createPinia } from 'pinia'import App from './App.vue'import router from './router'const app = createApp(App)app.use(createPinia())app.use(router)app.mount('#app')
- 創建 stores 資料夾,在裡面可以把要用的狀態分類,分別創立檔案
- 例如
count.ts
// stores/count.tsimport { defineStore } from 'pinia'import { computed, ref } from 'vue'export const useCountStore = defineStore('count', { const sum = ref(0) const increment = () => { sum.value ++ } const decrease = () => { sum.value -- } const bigSum = computed(() => { return sum.value * 100 }) return { sum, increment, decrease, bigSum }})
- 到要使用的 Vue 元件內引入
<!-- Count.vue --><template> <p>目前的數字是 {{ countStore.sum }}</p></template><script setup lang="ts">import { useCountStore } from '@/store/count'const countStore = useCountStore()</script>
- 改變 state 的方法
4-1. 在元件內直接修改
<!-- Count.vue --><template> <div>目前的數字是 {{ countStore.sum }}</div> <button type="button" @click="add">+</button></template><script setup lang="ts">import { useCountStore } from '@/store/count'const countStore = useCountStore()const add = () => { countStore.count++}</script>
4-2. 在 count.ts
內定義 action
- 新增
increment
方法
// stores/count.tsimport { defineStore } from 'pinia'import { computed, ref } from 'vue'export const useCountStore = defineStore('count', { const sum = ref(0) const increment = () => { sum.value ++ } const bigSum = computed(() => { return sum.value * 100 }) return { sum, bigSum, increment }})
- 到元件內引入
<!-- Count.vue --><template> <p>目前的數字是 {{ countStore.sum }}</p> <button type="button" @click="add">+</button></template><script setup lang="ts">import { useCountStore } from '@/store/count'const countStore = useCountStore()const add = () => { counterStore.increment()}</script>
注意! Pinia 的解構賦值
- 因為
countStore
是一個 reactive 建立的物件,直接解構賦值得到的是裡面的值,state
會失去響應式 - 需要使用
storeToRefs
來對state
,getter
的值做處理 reactive
和function
(action)不需要使用storeToRefs
<!-- Count.vue --><template> <p>目前的數字是 {{ sum }}</p> <p>{{ bigSum }}</p> <button type="button" @click="increment">+</button></template><script setup lang="ts">import { useCountStore } from '@/store/count'import { storeToRefs } from 'pinia'const countStore = useCountStore()const { sum, bigSum } = storeToRefs(countStore)const { increment } = countStore</script>
參考資料
# Vue # Pinia