Ver Fonte

fix(lifecycle): beforeUpdated should not be called if component is destroyed (#9171)

fix #8076
Matteo Fogli há 7 anos atrás
pai
commit
87bad80f0c

+ 1 - 1
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')
       }
     }

+ 37 - 0
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: '<div>{{todo.done}}</div>',
+        props: ['todo'],
+        destroyed,
+        beforeUpdate
+      })
+
+      const vm = new Vue({
+        template: `
+          <div>
+            <todo v-for="t in pendingTodos" :todo="t" :key="t.id"></todo>
+          </div>
+        `,
+        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', () => {