Skip to content

Commit

Permalink
fix(runtime-core): should not track deps in pre flush watcher callbacks
Browse files Browse the repository at this point in the history
fix #2728
  • Loading branch information
yyx990803 committed Mar 26, 2021
1 parent 22cc4a7 commit d5824b9
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 1 deletion.
38 changes: 38 additions & 0 deletions packages/runtime-core/__tests__/apiWatch.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -877,4 +877,42 @@ describe('api: watch', () => {
expect(instance).toBeDefined()
expect(source).toHaveBeenCalledWith(instance)
})

// #2728
test('pre watcher callbacks should not track dependencies', async () => {
const a = ref(0)
const b = ref(0)
const updated = jest.fn()

const Child = defineComponent({
props: ['a'],
updated,
watch: {
a() {
b.value
}
},
render() {
return h('div', this.a)
}
})

const Parent = defineComponent({
render() {
return h(Child, { a: a.value })
}
})

const root = nodeOps.createElement('div')
createApp(Parent).mount(root)

a.value++
await nextTick()
expect(updated).toHaveBeenCalledTimes(1)

b.value++
await nextTick()
// should not track b as dependency of Child
expect(updated).toHaveBeenCalledTimes(1)
})
})
11 changes: 10 additions & 1 deletion packages/runtime-core/src/renderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,14 @@ import {
flushPreFlushCbs,
SchedulerCb
} from './scheduler'
import { effect, stop, ReactiveEffectOptions, isRef } from '@vue/reactivity'
import {
effect,
stop,
ReactiveEffectOptions,
isRef,
pauseTracking,
resetTracking
} from '@vue/reactivity'
import { updateProps } from './componentProps'
import { updateSlots } from './componentSlots'
import { pushWarningContext, popWarningContext, warn } from './warning'
Expand Down Expand Up @@ -1567,9 +1574,11 @@ function baseCreateRenderer(
updateProps(instance, nextVNode.props, prevProps, optimized)
updateSlots(instance, nextVNode.children)

pauseTracking()
// props update may have triggered pre-flush watchers.
// flush them before the render update.
flushPreFlushCbs(undefined, instance.update)
resetTracking()
}

const patchChildren: PatchChildrenFn = (
Expand Down

0 comments on commit d5824b9

Please sign in to comment.