diff --git a/packages/reactivity/__tests__/computed.spec.ts b/packages/reactivity/__tests__/computed.spec.ts index 90987e86720..ff228ca0c0b 100644 --- a/packages/reactivity/__tests__/computed.spec.ts +++ b/packages/reactivity/__tests__/computed.spec.ts @@ -1029,4 +1029,19 @@ describe('reactivity/computed', () => { state.a++ expect(p.value).toBe(3) }) + + test('computed dep cleanup should not cause property dep to be deleted', () => { + const toggle = ref(true) + const state = reactive({ a: 1 }) + const p = computed(() => { + return toggle.value ? state.a : 111 + }) + const pp = computed(() => state.a) + effect(() => p.value) + + expect(pp.value).toBe(1) + toggle.value = false + state.a++ + expect(pp.value).toBe(2) + }) }) diff --git a/packages/reactivity/src/effect.ts b/packages/reactivity/src/effect.ts index d0b7c7bd9fb..20bbada505f 100644 --- a/packages/reactivity/src/effect.ts +++ b/packages/reactivity/src/effect.ts @@ -292,7 +292,7 @@ function prepareDeps(sub: Subscriber) { } } -function cleanupDeps(sub: Subscriber) { +function cleanupDeps(sub: Subscriber, fromComputed = false) { // Cleanup unsued deps let head let tail = sub.depsTail @@ -302,7 +302,7 @@ function cleanupDeps(sub: Subscriber) { if (link.version === -1) { if (link === tail) tail = prev // unused - remove it from the dep's subscribing effect list - removeSub(link) + removeSub(link, fromComputed) // also remove it from this effect's dep list removeDep(link) } else { @@ -394,7 +394,7 @@ export function refreshComputed(computed: ComputedRefImpl): undefined { } finally { activeSub = prevSub shouldTrack = prevShouldTrack - cleanupDeps(computed) + cleanupDeps(computed, true) computed.flags &= ~EffectFlags.RUNNING } }