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.ts
import { 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.ts
import { 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