From 87bad80f0cb9a30b95d9410120ff6e3e2022a723 Mon Sep 17 00:00:00 2001 From: Matteo Fogli Date: Tue, 11 Dec 2018 17:31:27 +0100 Subject: [PATCH] fix(lifecycle): beforeUpdated should not be called if component is destroyed (#9171) fix #8076 --- src/core/instance/lifecycle.js | 2 +- test/unit/features/options/lifecycle.spec.js | 37 ++++++++++++++++++++ 2 files changed, 38 insertions(+), 1 deletion(-) diff --git a/src/core/instance/lifecycle.js b/src/core/instance/lifecycle.js index 8d687b15725..d0b871be288 100644 --- a/src/core/instance/lifecycle.js +++ b/src/core/instance/lifecycle.js @@ -196,7 +196,7 @@ export function mountComponent ( // component's mounted hook), which relies on vm._watcher being already defined new Watcher(vm, updateComponent, noop, { before () { - if (vm._isMounted) { + if (vm._isMounted && !vm._isDestroyed) { callHook(vm, 'beforeUpdate') } } diff --git a/test/unit/features/options/lifecycle.spec.js b/test/unit/features/options/lifecycle.spec.js index ccc9d2106de..6f48ba06368 100644 --- a/test/unit/features/options/lifecycle.spec.js +++ b/test/unit/features/options/lifecycle.spec.js @@ -152,6 +152,43 @@ describe('Options lifecycle hooks', () => { expect(vm.$el.textContent).toBe('bar!') }).then(done) }) + + // #8076 + it('should not be called after destroy', done => { + const beforeUpdate = jasmine.createSpy('beforeUpdate') + const destroyed = jasmine.createSpy('destroyed') + + Vue.component('todo', { + template: '
{{todo.done}}
', + props: ['todo'], + destroyed, + beforeUpdate + }) + + const vm = new Vue({ + template: ` +
+ +
+ `, + data () { + return { + todos: [{ id: 1, done: false }] + } + }, + computed: { + pendingTodos () { + return this.todos.filter(t => !t.done) + } + } + }).$mount() + + vm.todos[0].done = true + waitForUpdate(() => { + expect(destroyed).toHaveBeenCalled() + expect(beforeUpdate).not.toHaveBeenCalled() + }).then(done) + }) }) describe('updated', () => {