expect(store.double).toBe(6)
})
+ it('allows overriding computed properties in setup stores', () => {
+ const useStore = defineStore('computed', () => {
+ const n = ref(0)
+ const double = computed(() => n.value * 2)
+ const doublePlusOne = computed(() => double.value + 1)
+ return { n, double, doublePlusOne }
+ })
+ const pinia = createTestingPinia()
+ const store = useStore(pinia)
+
+ // console.log('is same', d === toRaw(store).double._computed)
+
+ store.n++
+ expect(store.double).toBe(2)
+ // once the getter is overridden, it stays
+ store.double = 3
+ expect(store.double).toBe(3)
+ expect(store.doublePlusOne).toBe(4)
+ store.n++
+ expect(store.double).toBe(3)
+ expect(store.doublePlusOne).toBe(4)
+ // it can be set to undefined again to reset
+ // @ts-expect-error
+ store.double = undefined
+ expect(store.n).toBe(2)
+ expect(store.double).toBe(4)
+ expect(store.doublePlusOne).toBe(5)
+ // it works again
+ store.n++
+ expect(store.n).toBe(3)
+ expect(store.double).toBe(6)
+ expect(store.doublePlusOne).toBe(7)
+ })
+
it('actions are stubbed even when replaced by other plugins', () => {
const spy = vi.fn()
mount(Counter, {
isVue2,
set,
toRaw,
+ triggerRef,
} from 'vue-demi'
import type { ComputedRef, WritableComputedRef } from 'vue-demi'
import {
function WritableComputed({ store }: PiniaPluginContext) {
const rawStore = toRaw(store)
for (const key in rawStore) {
- const value = rawStore[key]
- if (isComputed(value)) {
+ const originalComputed = rawStore[key]
+ if (isComputed(originalComputed)) {
+ const originalFn = originalComputed.effect.fn
rawStore[key] = customRef((track, trigger) => {
- let internalValue: any
+ // override the computed with a new one
+ const overriddenFn = () =>
+ // @ts-expect-error: internal value
+ originalComputed._value
+ // originalComputed.effect.fn = overriddenFn
return {
get: () => {
track()
- return internalValue !== undefined ? internalValue : value.value
+ return originalComputed.value
},
set: (newValue) => {
- internalValue = newValue
+ // reset the computed to its original value by setting it to its initial state
+ if (newValue === undefined) {
+ originalComputed.effect.fn = originalFn
+ // @ts-expect-error: private api to remove the current cached value
+ delete originalComputed._value
+ // @ts-expect-error: private api to force the recomputation
+ originalComputed._dirty = true
+ } else {
+ originalComputed.effect.fn = overriddenFn
+ // @ts-expect-error: private api
+ originalComputed._value = newValue
+ }
+ // this allows to trigger the original computed in setup stores
+ triggerRef(originalComputed)
trigger()
},
}