From 56f4d64dae79f5eb2ddd7b4af38ed30dd85d2e8b Mon Sep 17 00:00:00 2001 From: Matteo Fogli Date: Mon, 10 Dec 2018 00:06:04 +0100 Subject: [PATCH 1/3] fix(lifecycle): beforeUpdated should not be called if component is destroyed --- 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..803db508733 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 beforeUpdated = jasmine.createSpy('beforeUpdated') + const destroyed = jasmine.createSpy('destroyed') + + Vue.component('todo', { + template: '
{{todo.done}}
', + props: ['todo'], + destroyed, + beforeUpdated + }) + + 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(beforeUpdated).not.toHaveBeenCalled() + }).then(done) + }) }) describe('updated', () => { From 2b99bf7d03647a0bc3cba447d1c4d48f81612b45 Mon Sep 17 00:00:00 2001 From: Eduardo San Martin Morote Date: Mon, 10 Dec 2018 12:00:33 +0100 Subject: [PATCH 2/3] Update test/unit/features/options/lifecycle.spec.js fix typo on lifecycle event name (tx @posva) Co-Authored-By: therealpecus --- test/unit/features/options/lifecycle.spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/unit/features/options/lifecycle.spec.js b/test/unit/features/options/lifecycle.spec.js index 803db508733..ef274ed64c6 100644 --- a/test/unit/features/options/lifecycle.spec.js +++ b/test/unit/features/options/lifecycle.spec.js @@ -186,7 +186,7 @@ describe('Options lifecycle hooks', () => { vm.todos[0].done = true waitForUpdate(() => { expect(destroyed).toHaveBeenCalled() - expect(beforeUpdated).not.toHaveBeenCalled() + expect(beforeUpdate).not.toHaveBeenCalled() }).then(done) }) }) From 5eb4fd6f77e82756753a958c12a6956bacbdb2de Mon Sep 17 00:00:00 2001 From: Matteo Fogli Date: Mon, 10 Dec 2018 12:28:40 +0100 Subject: [PATCH 3/3] fix(lifecycle): beforeUpdated should not be called if component is destroyed, fix #8076 fix references to beforeUpdate spy --- test/unit/features/options/lifecycle.spec.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/unit/features/options/lifecycle.spec.js b/test/unit/features/options/lifecycle.spec.js index ef274ed64c6..6f48ba06368 100644 --- a/test/unit/features/options/lifecycle.spec.js +++ b/test/unit/features/options/lifecycle.spec.js @@ -155,14 +155,14 @@ describe('Options lifecycle hooks', () => { // #8076 it('should not be called after destroy', done => { - const beforeUpdated = jasmine.createSpy('beforeUpdated') + const beforeUpdate = jasmine.createSpy('beforeUpdate') const destroyed = jasmine.createSpy('destroyed') Vue.component('todo', { template: '
{{todo.done}}
', props: ['todo'], destroyed, - beforeUpdated + beforeUpdate }) const vm = new Vue({