getters
Getter 完全等同于 Store 的 state 的计算值。具备缓存功能。它们可以用defineStore()中的getters属性定义。推荐使用箭头函数,并且它将接收state作为第一个参数:
export const useStore = defineStore('main', {
state: () => ({
count: 0,
}),
getters: {
doubleCount : (state) => state.count * 2,
},
})
大多数时候,getter 只会依赖state,但是,他们可能需要使用其他 getter。因此,在定义常规函数时,可以通过this访问整个 store 实例,但是在使用 TypeScript 时,必须定义返回类型,这是为了避免 TypeScript 的已知缺陷。使用箭头函数定义的 getter,不必定义返回类型;不使用this的 getter,也必定义返回类型。
export const useStore = defineStore('main', {
state: () => ({
count: 0,
}),
getters: {
// 自动推断出返回类型是一个 number
doubleCount(state) {
return state.count * 2
},
// 返回类型**必须**明确设置
doublePlusOne() : number {
// 整个 store 的 自动补全和类型标注
return this.doubleCount + 1
},
},
})
然后你可以直接在 store 实例上访问 getter:
<template>
<p>Double count is {{ store.doubleCount }}</p>
</template>
<script>
export default {
setup() {
const store = useCounterStore()
return { store }
},
}
</script>
访问其他 getter
与计算属性一样,您可以组合多个 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
},
},
})
向 getter 传递参数
getter 只是幕后的计算属性,所以不可以向它们传递任何参数。不过,你可以从 getter 返回一个函数,该函数可以接受任意参数:
export const useStore = defineStore('main', {
getters: {
getUserById : (state) => {
return (userId) => state.users.find((user) => user.id === userId)
},
},
})
并在组件中使用:
<script>
export default {
setup() {
const store = useStore()
return { getUserById: store.getUserById }
},
}
</script>
<template>
<p>User 2: {{ getUserById(2) }}</p>
</template>
请注意,当你这样做时,getter 不再缓存,它们只是一个被你调用的函数。不过,你可以在 getter 本身中缓存一些结果,虽然这种做法并不常见,但有证明表明它的性能会更好:
export const useStore = defineStore('main', {
getters: {
getActiveUserById(state) {
const activeUsers = state.users.filter((user) => user.active)
return (userId) => activeUsers.find((user) => user.id === userId)
},
},
})
访问其他 Store 的 getter
要使用其他存储 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()中,使用 getter
作为 store 的一个属性,你可以直接访问任何 getter(与 state 属性完全一样):
export default {
setup() {
const store = useCounterStore()
store.count = 3
store.doubleCount // 6
},
}
选项 API 组件中,使用 getter
对于以下示例,您可以假设已创建以下 Store:
// Example File Path:
// ./src/stores/counter.js
import { defineStore } from 'pinia'
export const useCounterStore = defineStore('counter', {
state: () => ({
count: 0,
}),
getters: {
doubleCount(state) {
return state.count * 2
},
},
})
在 setup()组件中调用 store
虽然 Composition API 并不适合所有人,但setup()钩子可以使在 Options API 中使用 Pinia 变得更容易。不需要额外的地图辅助功能!
import { useCounterStore } from '../stores/counter'
export default {
setup() {
const counterStore = useCounterStore()
return { counterStore }
},
computed : {
quadrupleCounter() {
return this.counterStore.doubleCount * 2
},
},
}
在无 setup()组件中调用 store
您可以使用上一部分 state 中使用的mapState()函数来映射到 getter:
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,
}),
},
}
