文章目錄
- 前言
- 一、pinia的getter簡單理解
- 二、訪問其他 store 的 getter
- 總結
前言
在 Pinia 中,getter 類似于 Vuex 中的 getter,允許你從 store 中派生出一些狀態,而不需要修改原始狀態。這使得我們可以創建基于現有狀態的計算屬性。
一、pinia的getter簡單理解
Getter 完全等同于 store 的 state 的計算值。可以通過 defineStore() 中的 getters 屬性來定義它們。推薦使用箭頭函數,并且它將接收 state 作為第一個參數。
export const useStore = defineStore('main', {state: () => ({count: 0,}),getters: {doubleCount: (state) => state.count * 2,},
})
大多數時候,getter 僅依賴 state,不過,有時它們也可能會使用其他 getter。因此,即使在使用常規函數定義 getter 時,我們也可以通過 this 訪問到整個 store 實例,但(在 TypeScript 中)必須定義返回類型。這是為了避免 TypeScript 的已知缺陷,不過這不影響用箭頭函數定義的 getter,也不會影響不使用 this 的 getter。
export const useStore = defineStore('main', {state: () => ({count: 0,}),getters: {// 自動推斷出返回類型是一個 numberdoubleCount(state) {return state.count * 2},// 返回類型**必須**明確設置doublePlusOne(): number {// 整個 store 的 自動補全和類型標注 ?return this.doubleCount + 1},},
})
然后你可以直接訪問 store 實例上的 getter 了:
<script setup>
import { useCounterStore } from './counterStore'
const store = useCounterStore()
</script>
<template><p>Double count is {{ store.doubleCount }}</p>
</template>
與計算屬性一樣,你也可以組合多個 getter。通過 this,你可以訪問到其他任何 getter。即使你沒有使用 TypeScript,你也可以用 JSDoc 來讓你的 IDE 提示類型。
export const useStore = defineStore('main', {state: () => ({count: 0,}),getters: {// 類型是自動推斷出來的,因為我們沒有使用 `this`doubleCount: (state) => state.count * 2,// 這里我們需要自己添加類型(在 JS 中使用 JSDoc)// 可以用 this 來引用 getter/*** 返回 count 的值乘以 2 加 1** @returns {number}*/doubleCountPlusOne() {// 自動補全 ?return this.doubleCount + 1},},
})
二、訪問其他 store 的 getter
想要使用另一個 store 的 getter 的話,那就直接在 getter 內使用就好:
import { useOtherStore } from './other-store'export const useStore = defineStore('main', {state: () => ({// ...}),getters: {otherGetter(state) {const otherStore = useOtherStore()return state.localData + otherStore.data},},
})
使用 setup() 時的用法
作為 store 的一個屬性,你可以直接訪問任何 getter(與 state 屬性完全一樣):
<script setup>
const store = useCounterStore()
store.count = 3
store.doubleCount // 6
</script>
雖然并不是每個開發者都會使用組合式 API,但 setup() 鉤子依舊可以使 Pinia 在選項式 API 中更易用。并且不需要額外的映射輔助函數!
<script>
import { useCounterStore } from '../stores/counter'export default defineComponent({setup() {const counterStore = useCounterStore()return { counterStore }},computed: {quadrupleCounter() {return this.counterStore.doubleCount * 2},},
})
</script>
這在將組件從選項式 API 遷移到組合式 API 時很有用,但應該只是一個遷移步驟,始終盡量不要在同一組件中混合兩種 API 樣式。
不使用 setup()
你可以使用前一節的 state 中的 mapState() 函數來將其映射為 getters:
import { mapState } from 'pinia'
import { useCounterStore } from '../stores/counter'export default {computed: {// 允許在組件中訪問 this.doubleCount// 與從 store.doubleCount 中讀取的相同...mapState(useCounterStore, ['doubleCount']),// 與上述相同,但將其注冊為 this.myOwnName...mapState(useCounterStore, {myOwnName: 'doubleCount',// 你也可以寫一個函數來獲得對 store 的訪問權double: store => store.doubleCount,}),},
}
總結
Pinia 的 getter 提供了一種方便的方式來派生出新的狀態,而不需要改變原始狀態。它們易于定義和使用,并且提供了緩存以提高性能。通過使用 getter,你可以創建復雜的狀態邏輯,同時保持代碼的清晰和組織。
小提示:從vue2到vue3的轉變,組合式寫法的思維需要慢慢熟悉。