Просмотр исходного кода

handle multiple activate hooks from mixin (fix #2305)

Evan You 10 лет назад
Родитель
Сommit
c63d6a3ba6

+ 24 - 3
src/directives/internal/component.js

@@ -139,12 +139,12 @@ export default {
     // actual mount
     this.unbuild(true)
     var self = this
-    var activateHook = this.Component.options.activate
+    var activateHooks = this.Component.options.activate
     var cached = this.getCached()
     var newComponent = this.build()
-    if (activateHook && !cached) {
+    if (activateHooks && !cached) {
       this.waitingFor = newComponent
-      activateHook.call(newComponent, function () {
+      callActivateHooks(activateHooks, newComponent, function () {
         if (self.waitingFor !== newComponent) {
           return
         }
@@ -358,3 +358,24 @@ export default {
     }
   }
 }
+
+/**
+ * Call activate hooks in order (asynchronous)
+ *
+ * @param {Array} hooks
+ * @param {Vue} vm
+ * @param {Function} cb
+ */
+
+function callActivateHooks (hooks, vm, cb) {
+  var total = hooks.length
+  var called = 0
+  hooks[0].call(vm, next)
+  function next () {
+    if (++called >= total) {
+      cb()
+    } else {
+      hooks[called].call(vm, next)
+    }
+  }
+}

+ 2 - 1
src/util/options.js

@@ -126,7 +126,8 @@ strats.detached =
 strats.beforeCompile =
 strats.compiled =
 strats.beforeDestroy =
-strats.destroyed = function (parentVal, childVal) {
+strats.destroyed =
+strats.activate = function (parentVal, childVal) {
   return childVal
     ? parentVal
       ? parentVal.concat(childVal)

+ 29 - 0
test/unit/specs/directives/internal/component_spec.js

@@ -282,6 +282,35 @@ describe('Component', function () {
     })
   })
 
+  it('multiple activate hooks', function (done) {
+    var mixinSpy = jasmine.createSpy('mixin activate')
+    new Vue({
+      el: el,
+      template: '<view-a></view-a>',
+      components: {
+        'view-a': {
+          template: 'AAA',
+          mixins: [{
+            activate: function (done) {
+              expect(el.textContent).toBe('')
+              mixinSpy()
+              done()
+            }
+          }],
+          activate: function (ready) {
+            setTimeout(function () {
+              expect(mixinSpy).toHaveBeenCalled()
+              expect(el.textContent).toBe('')
+              ready()
+              expect(el.textContent).toBe('AAA')
+              done()
+            }, 0)
+          }
+        }
+      }
+    })
+  })
+
   it('activate hook for dynamic components', function (done) {
     var next
     var vm = new Vue({