From 40eded3199bcb763a370ecdb15e09ed76973a12a Mon Sep 17 00:00:00 2001 From: RicardoErii <‘1974364190@qq.com’> Date: Mon, 15 Jan 2024 23:01:26 +0800 Subject: [PATCH] fix(reactivity): the scheduler handles the computed final dirtylevel --- .../reactivity/__tests__/computed.spec.ts | 22 +++++++++++++++++++ packages/reactivity/src/computed.ts | 5 +++++ 2 files changed, 27 insertions(+) diff --git a/packages/reactivity/__tests__/computed.spec.ts b/packages/reactivity/__tests__/computed.spec.ts index 6f5d7197157..c194c9a3b90 100644 --- a/packages/reactivity/__tests__/computed.spec.ts +++ b/packages/reactivity/__tests__/computed.spec.ts @@ -1,3 +1,4 @@ +import { h, nextTick, nodeOps, render, serializeInner } from '@vue/runtime-test' import { type DebuggerEvent, ITERATE_KEY, @@ -481,4 +482,25 @@ describe('reactivity/computed', () => { expect(provider.effect._dirtyLevel).toBe(DirtyLevels.Dirty) expect(provider.value).toBe('1foo') }) + + it('should be not dirty after deps mutate (mutate deps in computed)', async () => { + const state = reactive({}) + const consumer = computed(() => { + if (!('a' in state)) state.a = 1 + return state.a + }) + const Comp = { + setup: () => { + nextTick().then(() => { + state.a = 2 + }) + return () => consumer.value + }, + } + const root = nodeOps.createElement('div') + render(h(Comp), root) + await nextTick() + await nextTick() + expect(serializeInner(root)).toBe(`2`) + }) }) diff --git a/packages/reactivity/src/computed.ts b/packages/reactivity/src/computed.ts index 9f4d105c0ea..11a0df77318 100644 --- a/packages/reactivity/src/computed.ts +++ b/packages/reactivity/src/computed.ts @@ -44,6 +44,11 @@ export class ComputedRefImpl { this.effect = new ReactiveEffect( () => getter(this._value), () => triggerRefValue(this, DirtyLevels.MaybeDirty), + () => { + if (this.effect._dirtyLevel >= DirtyLevels.Dirty) { + triggerRefValue(this, DirtyLevels.MaybeDirty) + } + }, ) this.effect.computed = this this.effect.active = this._cacheable = !isSSR