Pinia-使用筆記

note-img

簡介

  • 在 Vue3 的 Composition API 推出後,官方推薦搭配使用的新工具
  • 移除了 Vuex 的 mutations
  • 對於 TypeScript 的支援度更高
  • 檔案結構更為扁平化,根據狀態的類型分類儲存
  • 支援 Server Side Rendering

核心概念

state

  • 如同  data,定義狀態的地方

getter

  • 如同  computed,state 的計算屬性

actions

  • 如同  methods,改變 state 的方法,包含非同步操作

如何使用

  • 以 Vue3 的 Composition API 寫法為例
  1. 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')
  1. 創建 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  }})
  1. 到要使用的 Vue 元件內引入
<!-- Count.vue --><template>  <p>目前的數字是 {{ countStore.sum }}</p></template><script setup lang="ts">import { useCountStore } from '@/store/count'const countStore = useCountStore()</script>
  1. 改變 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的值做處理
  • reactivefunction(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