Pinia Tip: Use Setup Stores for More Flexibility


Besides Option Stores you can also use Setup Stores to define stores in Pinia. They bring more flexibility as you can create watchers within a store and freely use any composable.
Defining Setup Store
Just like the setup function in the Vue Composition API, a function that sets up reactive properties and methods can be passed, which will return an object containing the properties and methods that should be made available:
export const useCounterStore = defineStore('counter', () => { const count = ref(0) const doubleCount = computed(() => count.value * 2) function increment() { count.value++ } return { count, doubleCount, increment }})
In Setup Stores:
ref()
s becomestate
propertiescomputed()
s becomegetters
function()
s becomeactions
When it comes to Vue's Composition API and Options API, select the one that you are most familiar with. If you are uncertain, start with the Option Stores.
Using Setup Store
At this point, we only defined the store but it won't be created until use...Store()
is called inside of setup()
:
<script setup>const store = useCounterStore()</script><template> <span>Counter: {{ store.count }}</span> <span>Double Count: {{ store.doubleCount }}</span> <button @click="store.increment">Increment</button></template>
The store
object has been wrapped with reactive
, so there is no need to include .value
when using getters, but similar to props
in setup
, it cannot be destructured. You need to use storeToRefs()
to destructure while keeping reactivity.
Bonus Tip
You can use composables that return writable state like VueUse useLocalStorage() directly within the state()
function:
export const useCounterStore = defineStore('counter', () => { const counterInfo = useLocalStorage('counterInfo', null) return { counterInfo }})
The same example using Option Store:
export const useCounterStore = defineStore('counter', () => { state: () => ({ // ... counterInfo: useLocalStorage('counterInfo', null), })})
If you liked this Vue tip, follow me on Twitter to get notified about new tips, blog posts, and more. Alternatively (or additionally), you can subscribe to my weekly Vue newsletter.