fix(runtime-core/scheduler): only allow watch callbacks to be self-triggering

fix #1740

Previous fix for #1727 caused `watchEffect` to also recursively trigger
itself on reactive array mutations which implicitly registers array
`.length` as dependencies and mutates it at the same time.

This fix limits recursive trigger behavior to only `watch()` callbacks
since code inside the callback do not register dependencies and
mutations are always explicitly intended.
This commit is contained in:
Evan You
2020-07-30 17:54:05 -04:00
parent ccf3362d4d
commit 09702e95b9
3 changed files with 108 additions and 31 deletions

View File

@@ -7,7 +7,7 @@ import {
ReactiveEffectOptions,
isReactive
} from '@vue/reactivity'
import { queueJob } from './scheduler'
import { queueJob, SchedulerJob } from './scheduler'
import {
EMPTY_OBJ,
isObject,
@@ -232,7 +232,7 @@ function doWatch(
}
let oldValue = isArray(source) ? [] : INITIAL_WATCHER_VALUE
const job = () => {
const job: SchedulerJob = () => {
if (!runner.active) {
return
}
@@ -258,6 +258,10 @@ function doWatch(
}
}
// important: mark the job as a watcher callback so that scheduler knows it
// it is allowed to self-trigger (#1727)
job.cb = !!cb
let scheduler: (job: () => any) => void
if (flush === 'sync') {
scheduler = job