fix(reactivity): fix regression for computed with mutation (#10119)

close #10114
This commit is contained in:
Doctor Wu 2024-01-15 23:38:57 +08:00 committed by GitHub
parent 3cd3a44ed3
commit 20f62afaaf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 22 additions and 9 deletions

View File

@ -1,3 +1,4 @@
import { h, nextTick, nodeOps, render, serializeInner } from '@vue/runtime-test'
import { import {
type DebuggerEvent, type DebuggerEvent,
ITERATE_KEY, ITERATE_KEY,
@ -470,15 +471,24 @@ describe('reactivity/computed', () => {
expect(c2.effect._dirtyLevel).toBe(DirtyLevels.NotDirty) expect(c2.effect._dirtyLevel).toBe(DirtyLevels.NotDirty)
}) })
it('should work when chained(ref+computed)', () => { it('should be not dirty after deps mutate (mutate deps in computed)', async () => {
const value = ref(0) const state = reactive<any>({})
const consumer = computed(() => { const consumer = computed(() => {
value.value++ if (!('a' in state)) state.a = 1
return 'foo' return state.a
}) })
const provider = computed(() => value.value + consumer.value) const Comp = {
expect(provider.value).toBe('0foo') setup: () => {
expect(provider.effect._dirtyLevel).toBe(DirtyLevels.Dirty) nextTick().then(() => {
expect(provider.value).toBe('1foo') state.a = 2
})
return () => consumer.value
},
}
const root = nodeOps.createElement('div')
render(h(Comp), root)
await nextTick()
await nextTick()
expect(serializeInner(root)).toBe(`2`)
}) })
}) })

View File

@ -295,7 +295,10 @@ export function triggerEffects(
// when recurse effect is running, dep map could have outdated items // when recurse effect is running, dep map could have outdated items
continue continue
} }
if (effect._dirtyLevel < dirtyLevel) { if (
effect._dirtyLevel < dirtyLevel &&
!(effect._runnings && !effect.allowRecurse)
) {
const lastDirtyLevel = effect._dirtyLevel const lastDirtyLevel = effect._dirtyLevel
effect._dirtyLevel = dirtyLevel effect._dirtyLevel = dirtyLevel
if (lastDirtyLevel === DirtyLevels.NotDirty) { if (lastDirtyLevel === DirtyLevels.NotDirty) {