From e84c4a608e9dc96fb2a4a29d538bcc64f26103a2 Mon Sep 17 00:00:00 2001 From: Evan You Date: Thu, 5 Sep 2024 18:58:40 +0800 Subject: [PATCH] fix(reactivity): self-referencing computed should refresh ref: https://github.com/vuejs/core/pull/11797#issuecomment-2330738633 --- packages/reactivity/__tests__/computed.spec.ts | 7 ++++--- packages/reactivity/src/computed.ts | 2 +- packages/reactivity/src/effect.ts | 3 --- 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/packages/reactivity/__tests__/computed.spec.ts b/packages/reactivity/__tests__/computed.spec.ts index 31daef559..e0b47cf56 100644 --- a/packages/reactivity/__tests__/computed.spec.ts +++ b/packages/reactivity/__tests__/computed.spec.ts @@ -594,7 +594,7 @@ describe('reactivity/computed', () => { v.value += ' World' await nextTick() - expect(serializeInner(root)).toBe('Hello World World World') + expect(serializeInner(root)).toBe('Hello World World World World') // expect(COMPUTED_SIDE_EFFECT_WARN).toHaveBeenWarned() }) @@ -892,7 +892,7 @@ describe('reactivity/computed', () => { v.value += ' World' await nextTick() expect(serializeInner(root)).toBe( - 'Hello World World World | Hello World World World', + 'Hello World World World World | Hello World World World World', ) }) @@ -962,6 +962,7 @@ describe('reactivity/computed', () => { }) }) + // #11797 test('should prevent endless recursion in self-referencing computed getters', async () => { const Comp = defineComponent({ data() { @@ -998,7 +999,7 @@ describe('reactivity/computed', () => { }) const root = nodeOps.createElement('div') render(h(Comp), root) - expect(serializeInner(root)).toBe(`

`) + expect(serializeInner(root)).toBe(`

Step 1

`) triggerEvent(root.children[1] as TestElement, 'click') await nextTick() expect(serializeInner(root)).toBe(`

Step 2

`) diff --git a/packages/reactivity/src/computed.ts b/packages/reactivity/src/computed.ts index aa5d20790..d2dd67bf9 100644 --- a/packages/reactivity/src/computed.ts +++ b/packages/reactivity/src/computed.ts @@ -111,9 +111,9 @@ export class ComputedRefImpl implements Subscriber { * @internal */ notify(): void { + this.flags |= EffectFlags.DIRTY // avoid infinite self recursion if (activeSub !== this) { - this.flags |= EffectFlags.DIRTY this.dep.notify() } else if (__DEV__) { // TODO warn diff --git a/packages/reactivity/src/effect.ts b/packages/reactivity/src/effect.ts index 88493e4e9..51df32e99 100644 --- a/packages/reactivity/src/effect.ts +++ b/packages/reactivity/src/effect.ts @@ -345,9 +345,6 @@ function isDirty(sub: Subscriber): boolean { * @internal */ export function refreshComputed(computed: ComputedRefImpl): false | undefined { - if (computed.flags & EffectFlags.RUNNING) { - return false - } if ( computed.flags & EffectFlags.TRACKING && !(computed.flags & EffectFlags.DIRTY)