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.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
  }

})
  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.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的值做處理
  • 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