Skip to content

Commit d5824b9

Browse files
committed
fix(runtime-core): should not track deps in pre flush watcher callbacks
fix #2728
1 parent 22cc4a7 commit d5824b9

File tree

2 files changed

+48
-1
lines changed

2 files changed

+48
-1
lines changed

packages/runtime-core/__tests__/apiWatch.spec.ts

+38
Original file line numberDiff line numberDiff line change
@@ -877,4 +877,42 @@ describe('api: watch', () => {
877877
expect(instance).toBeDefined()
878878
expect(source).toHaveBeenCalledWith(instance)
879879
})
880+
881+
// #2728
882+
test('pre watcher callbacks should not track dependencies', async () => {
883+
const a = ref(0)
884+
const b = ref(0)
885+
const updated = jest.fn()
886+
887+
const Child = defineComponent({
888+
props: ['a'],
889+
updated,
890+
watch: {
891+
a() {
892+
b.value
893+
}
894+
},
895+
render() {
896+
return h('div', this.a)
897+
}
898+
})
899+
900+
const Parent = defineComponent({
901+
render() {
902+
return h(Child, { a: a.value })
903+
}
904+
})
905+
906+
const root = nodeOps.createElement('div')
907+
createApp(Parent).mount(root)
908+
909+
a.value++
910+
await nextTick()
911+
expect(updated).toHaveBeenCalledTimes(1)
912+
913+
b.value++
914+
await nextTick()
915+
// should not track b as dependency of Child
916+
expect(updated).toHaveBeenCalledTimes(1)
917+
})
880918
})

packages/runtime-core/src/renderer.ts

+10-1
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,14 @@ import {
4848
flushPreFlushCbs,
4949
SchedulerCb
5050
} from './scheduler'
51-
import { effect, stop, ReactiveEffectOptions, isRef } from '@vue/reactivity'
51+
import {
52+
effect,
53+
stop,
54+
ReactiveEffectOptions,
55+
isRef,
56+
pauseTracking,
57+
resetTracking
58+
} from '@vue/reactivity'
5259
import { updateProps } from './componentProps'
5360
import { updateSlots } from './componentSlots'
5461
import { pushWarningContext, popWarningContext, warn } from './warning'
@@ -1567,9 +1574,11 @@ function baseCreateRenderer(
15671574
updateProps(instance, nextVNode.props, prevProps, optimized)
15681575
updateSlots(instance, nextVNode.children)
15691576

1577+
pauseTracking()
15701578
// props update may have triggered pre-flush watchers.
15711579
// flush them before the render update.
15721580
flushPreFlushCbs(undefined, instance.update)
1581+
resetTracking()
15731582
}
15741583

15751584
const patchChildren: PatchChildrenFn = (

0 commit comments

Comments
 (0)