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
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with
34 additions and
0 deletions
-
src/core/instance/state.js
-
test/unit/features/instance/methods-lifecycle.spec.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() |
|
|
|
|
|
@ -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', () => { |
|
|
|