]> git.ipfire.org Git - thirdparty/vuejs/pinia.git/commitdiff
fix: avoid immediate computing with `storeToRefs`
authorEduardo San Martin Morote <posva13@gmail.com>
Thu, 28 Nov 2024 13:33:19 +0000 (14:33 +0100)
committerEduardo San Martin Morote <posva13@gmail.com>
Thu, 28 Nov 2024 13:33:19 +0000 (14:33 +0100)
Fix #2812

packages/pinia/__tests__/storeToRefs.spec.ts
packages/pinia/src/storeToRefs.ts

index d1110e8c131a4675dd7b43bbc88a600041a23740..17b4a3540ebdefec176b49487da777d53a950337 100644 (file)
@@ -1,4 +1,4 @@
-import { describe, beforeEach, it, expect } from 'vitest'
+import { describe, beforeEach, it, expect, vi } from 'vitest'
 import { computed, reactive, ref, ToRefs } from 'vue'
 import { createPinia, defineStore, setActivePinia, storeToRefs } from '../src'
 import { set } from 'vue-demi'
@@ -190,6 +190,19 @@ describe('storeToRefs', () => {
     expect(double.value).toEqual(1)
   })
 
+  it('does not trigger getters', () => {
+    const n = ref(0)
+    const spy = vi.fn(() => n.value * 2)
+    const store = defineStore('a', () => {
+      const double = computed(spy)
+      return { n, double }
+    })()
+
+    expect(spy).toHaveBeenCalledTimes(0)
+    storeToRefs(store)
+    expect(spy).toHaveBeenCalledTimes(0)
+  })
+
   tds(() => {
     const store1 = defineStore('a', () => {
       const n = ref(0)
index 3a1cec09f5a65feda11dca02c7b69a37fa1c520f..3278b0c698f1f01221d7cbd5d8bea8dd24719195 100644 (file)
@@ -1,4 +1,5 @@
 import {
+  computed,
   ComputedRef,
   isReactive,
   isRef,
@@ -99,7 +100,19 @@ export function storeToRefs<SS extends StoreGeneric>(
     const refs = {} as StoreToRefs<SS>
     for (const key in rawStore) {
       const value = rawStore[key]
-      if (isRef(value) || isReactive(value)) {
+      // There is no native method to check for a computed
+      // https://github.com/vuejs/core/pull/4165
+      if (value.effect) {
+        // @ts-expect-error: too hard to type correctly
+        refs[key] =
+          // ...
+          computed({
+            get: () => store[key],
+            set(value) {
+              store[key] = value
+            },
+          })
+      } else if (isRef(value) || isReactive(value)) {
         // @ts-expect-error: the key is state or getter
         refs[key] =
           // ---