# Getters
-Getters are exactly the equivalent of [computed values](https://v3.vuejs.org/guide/reactivity-computed-watchers.html#computed-values) for the state of a Store. They can be defined with the `getters` property in `defineStore()`:
+Getters are exactly the equivalent of [computed values](https://v3.vuejs.org/guide/reactivity-computed-watchers.html#computed-values) for the state of a Store. They can be defined with the `getters` property in `defineStore()`. They receive the `state` as the first parameter **to encourage** the usage of arrow function:
```js
export const useStore = defineStore({
counter: 0,
}),
getters: {
- doubleCount() {
- return this.counter * 2
- },
+ doubleCount: (state) => state.counter * 2,
},
})
```
-Like [actions](./actions.md), getters get access to the _whole store instance_ through `this` with **full typing (and autocompletion ✨) support**.
+Most of the time, getters will only rely on the state, however, they might need to use other getters. Because of this, we can get access to the _whole store instance_ through `this` when defining a regular function **but it is necessary to define the type of the return type (in TypeScript)**. This is due to a known limitation in TypeScript and **doesn't affect getters defined with an arrow function nor getters not using `this`**:
+
+```ts
+export const useStore = defineStore({
+ id: 'main',
+ state: () => ({
+ counter: 0,
+ }),
+ getters: {
+ // automatically infers the return type as a number
+ doubleCount(state) {
+ return state.counter * 2
+ },
+ // the return type **must** be explicitly set
+ doublePlusOne(): number {
+ // autocompletion and typings for the whole store ✨
+ return this.state * 2 + 1
+ },
+ },
+})
+```
Then you can access the getter directly on the store instance:
## Accessing other getters
-As with computed properties, you can combine multiple getters. Access any other getter via `this`:
+As with computed properties, you can combine multiple getters. Access any other getter via `this`. Even if you are not using TypeScript, you can hint your IDE for types with the [JSDoc](https://jsdoc.app/tags-returns.html):
```js
export const useStore = defineStore({
counter: 0,
}),
getters: {
- doubleCount() {
- return this.counter * 2
- },
+ // 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
// ...
}),
getters: {
- otherGetter() {
+ otherGetter(state) {
const otherStore = useOtherStore()
- return this.localData + otherStore.data
+ return state.localData + otherStore.data
},
},
})
const useCounterStore = defineStore({
id: 'counter',
state: () => ({ count: 0 }),
- getters: { double: state => state.count * 2 },
+ getters: {
+ double: (state) => state.count * 2,
+ },
actions: {
increment() {
this.count++
}
}
})
+
const useUserStore = defineStore({ id: 'user' })
export default {
nextId: 0,
}),
getters: {
- finishedTodos() {
+ finishedTodos(state) {
// autocompletion! ✨
- return this.todos.filter((todo) => todo.isFinished)
+ return state.todos.filter((todo) => todo.isFinished)
},
- unfinishedTodos() {
- return this.todos.filter((todo) => !todo.isFinished)
+ unfinishedTodos(state) {
+ return state.todos.filter((todo) => !todo.isFinished)
},
- filteredTodos() {
+ /**
+ * @returns {{ text: string, id: number, isFinished: boolean }[]}
+ */
+ filteredTodos(state) {
if (this.filter === 'finished') {
// call other getters with autocompletion ✨
return this.finishedTodos