Browse Source

fix: pause dep collection during immediate watcher invocation (#11943)

Co-authored-by: Eduardo San Martin Morote <posva@users.noreply.github.com>
dev
Ben Delaney 4 years ago
committed by GitHub
parent
commit
987f322b8f
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      src/core/instance/state.js
  2. 32
      test/unit/features/instance/methods-lifecycle.spec.js

2
src/core/instance/state.js

@ -355,11 +355,13 @@ export function stateMixin (Vue: Class<Component>) {
options.user = true
const watcher = new Watcher(vm, expOrFn, cb, options)
if (options.immediate) {
pushTarget()
try {
cb.call(vm, watcher.value)
} catch (error) {
handleError(error, vm, `callback for immediate watcher "${watcher.expression}"`)
}
popTarget()
}
return function unwatchFn () {
watcher.teardown()

32
test/unit/features/instance/methods-lifecycle.spec.js

@ -53,6 +53,38 @@ describe('Instance methods lifecycle', () => {
}
}).$mount()
})
it('Dep.target should be undefined during invocation of child immediate watcher', done => {
let calls = 0
const childData = { a: 1 }
const parentUpdate = jasmine.createSpy()
new Vue({
template: '<div><my-component></my-component></div>',
updated: parentUpdate,
components: {
myComponent: {
template: '<div>{{ a }}</div>',
data() {
return childData
},
watch: {
anything: {
handler() {
++calls
this.a
},
immediate: true
}
}
}
}
}).$mount()
expect(calls).toBe(1)
childData.a++
waitForUpdate(() => {
expect(parentUpdate).not.toHaveBeenCalled()
}).then(done)
})
})
describe('$destroy', () => {

Loading…
Cancel
Save