getter
与Store
状态的计算值完全相同。它们可以用defineStore()
中的getters
属性来定义。它们接收state
作为第一个参数,以鼓励使用箭头函数:
export const useStore = defineStore('main', {
state: () => ({
counter: 0
}),
getters: {
doubleCount: (state) => state.counter * 2
}
})
大多数时候,getter
只依赖于状态,但是,它们可能需要使用其他getter
。因此,当定义一个常规函数时,我们可以通过这个函数访问整个store
实例,但需要定义返回的类型(在TypeScript
中)。这是由于TypeScript
中的一个已知限制,不会影响用箭头函数定义的getter
,也不会影响不使用This
的getter
:
export const useStore = defineStore('mian', {
state: (() => {
counter: 0
}),
getters: {
// 自动推断类型为nubmer
doubleCount(state) {
return state.counter * 2
},
// 返回的类型必须被设置
doublePlusOne(): number {
// autocompletion and typings for the whole store
return this.doubleCount + 1
}
}
})
然后你可以直接访问store
实例getter
:
Double count is {{ store.doubleCount }}
与计算属性一样,您可以组合多个getters
。通过this
访问任何其他的getters
。即使您不使用TypeScript
,您也可以使用JSDoc
提示IDE输入的类型
export const useStore = defineStore('main', {
state: () => ({
counter: 0,
}),
getters: {
// type is automatically inferred because we are not using `this`
doubleCount: (state) => state.counter * 2,
// here we need to add the type ourselves (using JSDoc in JS). We can also
// use this to document the getter
/**
* Returns the counter value times two plus one.
*
* @returns {number}
*/
doubleCountPlusOne() {
// autocompletion ✨
return this.doubleCount + 1
},
},
})
Getter
只是后台的计算属性,所以不可能向它们传递任何参数。但是,你可以从getter
返回一个函数来接受任何参数:
export const useStore = defineStore('main', {
getters: {
getUserById: (state) => {
return (userId) => state.users.find((user) => user.id === userId)
},
},
})
然后再组件中这样使用:
User 2: {{ getUserById(2) }}
注意,当这样做时,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
中使用它:
import { useOtherStore } from './other-store'
export const useStore = defineStore('main', {
state: () => ({
// ...
}),
getters: {
otherGetter(state) {
const otherStore = useOtherStore()
return state.localData + otherStore.data
},
},
})
你可以直接访问任何getter
作为存储的属性(完全像state
属性):
export default {
setup() {
const store = useStore()
store.counter = 3
store.doubleCount // 6
},
}
对于以下示例,您可以假设创建了以下store
:
// Example File Path:
// ./src/stores/counterStore.js
import { defineStore } from 'pinia',
const useCounterStore = defineStore('counterStore', {
state: () => ({
counter: 0
}),
getters: {
doubleCounter() {
return this.counter * 2
}
}
})
虽然Composition API
并不适合所有人,但是setup()
钩子可以让Pinia
更容易在Options API
中使用。不需要额外的帮助函数!
import { useCounterStore } from '../stores/counterStore'
export default {
setup() {
const counterStore = useCounterStore()
return { counterStore }
},
computed: {
quadrupleCounter() {
return counterStore.doubleCounter * 2
},
},
}
你可以使用在前一节中使用的mapState()
函数来映射到getter
:
import { mapState } from 'pinia'
import { useCounterStore } from '../stores/counterStore'
export default {
computed: {
// gives access to this.doubleCounter inside the component
// same as reading from store.doubleCounter
...mapState(useCounterStore, ['doubleCount'])
// same as above but registers it as this.myOwnName
...mapState(useCounterStore, {
myOwnName: 'doubleCounter',
// you can also write a function that gets access to the store
double: store => store.doubleCount,
}),
},
}