Pinia: How to reset stores created with function/setup syntax
What is Pinia
Pinia is a state management solution for Vue 3.
If you are thinking "Oh, another tool?", the truth is that Pinia can be thought as the next version of Vuex 4. Or as Evan said:
Evan You@youyuxi@olemarius @VueDose @vuejs Pinia is de facto Vuex 5! At this point itβs really a naming/branding issue.08:49 AM - 24 Nov 2021
Pinia shares a lot of similarities with Vuex but it's simpler, type safe and extensible!
If you haven't tried it yet, checkout the docs to get started!
Object and Function stores
There are two ways of creating a store with Pinia.
Object syntax:
import { defineStore } from 'pinia'
export const useStore = defineStore('main', {
state: () => ({
counter: 0,
}),
getters: {
doubleCount: (state) => state.counter * 2,
},
actions: {
increment() {
this.counter++
},
}
})
Function syntax:
import { ref, computed } from 'vue'
import { defineStore } from 'pinia'
export const useStore = defineStore('main', () => {
const counter = ref(0)
const doubleCounter = computed(() => counter.value * 2)
function increment() {
counter.value++
}
return {
counter,
doubleCounter,
increment
}
})
The Object syntax looks very similar to Vuex. The Function syntax is similar to a component setup()
method where we manually define reactivity.
How to reset the store with Object syntax
When using Object syntax you can simply call the built-in $reset
method:
<script setup>
import { useStore } from './useStore'
const store = useStore()
store.$reset // π
</script>
However, with Function syntax the built-in $reset
method simply throws an error:
π: Store "main" is build using the setup syntax and does not implement $reset().
How to reset the store with Function syntax
In order to make $reset
method work with Function syntax we are going to create a Pinia plugin: β¨
reset-store.js
import cloneDeep from 'lodash.clonedeep'
export default function resetStore({ store }) {
const initialState = cloneDeep(store.$state)
store.$reset = () => store.$patch(cloneDeep(initialState))
}
Here, we deep-copy the initial state of the store with lodash.clonedeep and we add the $reset
function which sets the state to its initial value. It's important to deep-copy the state again in order to remove references to the copy itself.
With store.$patch
we apply multiple changes at the same time. Read more on the docs.
Then in main.js
or wherever you initialize Pinia:
// ...
import { resetStore } from './reset-store'
//...
const pinia = createPinia()
pinia.use(resetStore)
app.use(pinia)
//...
See demo here on Stackblitz or embed:
Learn more about Pinia plugins
Conclusion
Awesome! Now no matter if we use Object or Function syntax, $reset
method works! π₯³π₯³
I want to thank on of the best Vue devs out there @tony19 for his answer on StackOverflow.