```js
import { set, toRef } from '@vue/composition-api'
pinia.use(({ store }) => {
- if (!Object.prototype.hasOwnProperty(store.$state, 'hello')) {
+ if (!Object.prototype.hasOwnProperty(store.$state, 'secret')) {
const secretRef = ref('secret')
// If the data is meant to be used during SSR, you should
// set it on the `$state` property so it is serialized and
:::
+#### Resetting state added in plugins
+
+By default, `$reset()` will not reset state added by plugins but you can override it to also reset the state you add:
+
+```js
+import { toRef, ref } from 'vue'
+
+pinia.use(({ store }) => {
+ // this is the same code as above for reference
+ if (!Object.prototype.hasOwnProperty(store.$state, 'hasError')) {
+ const hasError = ref(false)
+ store.$state.hasError = hasError
+ }
+ store.hasError = toRef(store.$state, 'hasError')
+
+ // make sure to set the context (`this`) to the store
+ const originalReset = store.$reset.bind(store)
+
+ // override the $reset function
+ return {
+ $reset() {
+ originalReset()
+ store.hasError = false
+ }
+ }
+})
+```
+
## Adding new external properties
When adding external properties, class instances that come from other libraries, or simply things that are not reactive, you should wrap the object with `markRaw()` before passing it to pinia. Here is an example adding the router to every store:
}
describe('store plugins', () => {
- const useStore = defineStore({
- id: 'test',
-
+ const useStore = defineStore('test', {
actions: {
incrementN() {
return this.pluginN++
store.idFromPlugin == 'hello'
})
+ it('overrides $reset', () => {
+ const pinia = createPinia()
+
+ const useStore = defineStore('main', {
+ state: () => ({ n: 0 }),
+ })
+
+ mount({ template: 'none' }, { global: { plugins: [pinia] } })
+
+ pinia.use(({ app, store }) => {
+ if (!store.$state.hasOwnProperty('pluginN')) {
+ // @ts-expect-error: cannot be a ref yet
+ store.$state.pluginN = ref(20)
+ }
+ // @ts-expect-error: TODO: allow setting refs
+ store.pluginN = toRef(store.$state, 'pluginN')
+
+ const originalReset = store.$reset.bind(store)
+ return {
+ uid: app._uid,
+ $reset() {
+ originalReset()
+ store.pluginN = 20
+ },
+ }
+ })
+
+ const store = useStore(pinia)
+
+ store.pluginN = 200
+ store.$reset()
+ expect(store.$state.pluginN).toBe(20)
+ expect(store.pluginN).toBe(20)
+ })
+
it('can install plugins before installing pinia', () => {
const pinia = createPinia()
store = createSetupStore(id, setup, options, pinia, hot, true)
- store.$reset = function $reset() {
- const newState = state ? state() : {}
- // we use a patch to group all changes into one single subscription
- this.$patch(($state) => {
- assign($state, newState)
- })
- }
-
return store as any
}
)
}
- /* istanbul ignore next */
- const $reset = __DEV__
+ const $reset = isOptionsStore
+ ? function $reset(this: _StoreWithState<Id, S, G, A>) {
+ const { state } = options as DefineStoreOptions<Id, S, G, A>
+ const newState = state ? state() : {}
+ // we use a patch to group all changes into one single subscription
+ this.$patch(($state) => {
+ assign($state, newState)
+ })
+ }
+ : /* istanbul ignore next */
+ __DEV__
? () => {
throw new Error(
`🍍: Store "${$id}" is built using the setup syntax and does not implement $reset().`