Procházet zdrojové kódy

trigger event after reassigned state - Fix #5191 (#5233)

kingwl před 9 roky
rodič
revize
4c4a2ab65f

+ 6 - 4
src/core/observer/scheduler.js

@@ -69,10 +69,14 @@ function flushSchedulerQueue () {
     }
   }
 
+  // reset scheduler before updated hook called
+  const oldQueue = queue.slice()
+  resetSchedulerState()
+
   // call updated hooks
-  index = queue.length
+  index = oldQueue.length
   while (index--) {
-    watcher = queue[index]
+    watcher = oldQueue[index]
     vm = watcher.vm
     if (vm._watcher === watcher && vm._isMounted) {
       callHook(vm, 'updated')
@@ -84,8 +88,6 @@ function flushSchedulerQueue () {
   if (devtools && config.devtools) {
     devtools.emit('flush')
   }
-
-  resetSchedulerState()
 }
 
 /**

+ 31 - 0
test/unit/modules/observer/scheduler.spec.js

@@ -144,4 +144,35 @@ describe('Scheduler', () => {
       expect(callOrder).toEqual([1, 2, 3])
     }).then(done)
   })
+
+  // Github issue #5191
+  it('emit should work when updated hook called', done => {
+    const el = document.createElement('div')
+    const vm = new Vue({
+      template: `<div><child @change="bar" :foo="foo"></child></div>`,
+      data: {
+        foo: 0
+      },
+      methods: {
+        bar: spy
+      },
+      components: {
+        child: {
+          template: `<div>{{foo}}</div>`,
+          props: ['foo'],
+          updated () {
+            this.$emit('change')
+          }
+        }
+      }
+    }).$mount(el)
+    vm.$nextTick(() => {
+      vm.foo = 1
+      vm.$nextTick(() => {
+        expect(vm.$el.innerHTML).toBe('<div>1</div>')
+        expect(spy).toHaveBeenCalled()
+        done()
+      })
+    })
+  })
 })