]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
fix(reactivity): do not remove dep from depsMap when unsubbed by computed
authorEvan You <evan@vuejs.org>
Fri, 20 Sep 2024 15:39:33 +0000 (23:39 +0800)
committerEvan You <evan@vuejs.org>
Fri, 20 Sep 2024 15:39:59 +0000 (23:39 +0800)
follow up of 235ea4772 after discovering regression in vant ecosystem-ci tests

packages/reactivity/__tests__/computed.spec.ts
packages/reactivity/src/effect.ts

index 543c9c6e770e5c286492e7fee5df6913a82722e8..90987e867205352bd5b6aa316c5ea5aa98e88f01 100644 (file)
@@ -1006,9 +1006,27 @@ describe('reactivity/computed', () => {
     expect(serializeInner(root)).toBe(`<button>Step</button><p>Step 2</p>`)
   })
 
-  it('manual trigger computed', () => {
+  test('manual trigger computed', () => {
     const cValue = computed(() => 1)
     triggerRef(cValue)
     expect(cValue.value).toBe(1)
   })
+
+  test('computed should remain live after losing all subscribers', () => {
+    const toggle = ref(true)
+    const state = reactive({
+      a: 1,
+    })
+    const p = computed(() => state.a + 1)
+    const pp = computed(() => {
+      return toggle.value ? p.value : 111
+    })
+
+    const { effect: e } = effect(() => pp.value)
+    e.stop()
+
+    expect(p.value).toBe(2)
+    state.a++
+    expect(p.value).toBe(3)
+  })
 })
index 4428b8df256281a3d440f358737af62a02f5ba7d..d0b7c7bd9fbdc94d149bae8ae1f7555ccad9c232 100644 (file)
@@ -399,7 +399,7 @@ export function refreshComputed(computed: ComputedRefImpl): undefined {
   }
 }
 
-function removeSub(link: Link) {
+function removeSub(link: Link, fromComputed = false) {
   const { dep, prevSub, nextSub } = link
   if (prevSub) {
     prevSub.nextSub = nextSub
@@ -425,9 +425,9 @@ function removeSub(link: Link) {
       // value can be GCed
       dep.computed.flags &= ~EffectFlags.TRACKING
       for (let l = dep.computed.deps; l; l = l.nextDep) {
-        removeSub(l)
+        removeSub(l, true)
       }
-    } else if (dep.map) {
+    } else if (dep.map && !fromComputed) {
       // property dep, remove it from the owner depsMap
       dep.map.delete(dep.key)
       if (!dep.map.size) targetMap.delete(dep.target!)