فهرست منبع

fix attach/ready hooks (fix #1005)

Evan You 11 سال پیش
والد
کامیت
62041458e5
3فایلهای تغییر یافته به همراه43 افزوده شده و 6 حذف شده
  1. 1 2
      src/api/lifecycle.js
  2. 8 4
      src/instance/events.js
  3. 34 0
      test/unit/specs/misc_spec.js

+ 1 - 2
src/api/lifecycle.js

@@ -23,12 +23,11 @@ exports.$mount = function (el) {
   this._compile(el)
   this._isCompiled = true
   this._callHook('compiled')
+  this._initDOMHooks()
   if (_.inDoc(this.$el)) {
     this._callHook('attached')
-    this._initDOMHooks()
     ready.call(this)
   } else {
-    this._initDOMHooks()
     this.$once('hook:attached', ready)
   }
   return this

+ 8 - 4
src/instance/events.js

@@ -81,8 +81,10 @@ exports._initDOMHooks = function () {
  */
 
 function onAttached () {
-  this._isAttached = true
-  this.$children.forEach(callAttach)
+  if (!this._isAttached) {
+    this._isAttached = true
+    this.$children.forEach(callAttach)
+  }
 }
 
 /**
@@ -102,8 +104,10 @@ function callAttach (child) {
  */
 
 function onDetached () {
-  this._isAttached = false
-  this.$children.forEach(callDetach)
+  if (this._isAttached) {
+    this._isAttached = false
+    this.$children.forEach(callDetach)
+  }
 }
 
 /**

+ 34 - 0
test/unit/specs/misc_spec.js

@@ -80,4 +80,38 @@ describe('Misc', function () {
     expect(el.innerHTML.replace(xmlns, '')).toBe('<svg><text>1</text><text>2</text><text>3</text></svg>')
   })
 
+  // #1005
+  it('call attach/ready/detach hook for child components', function () {
+    Vue.options.replace = true
+    var el = document.createElement('div')
+    var logs = []
+    function log (n) {
+      return function () {
+        logs.push(n)
+      }
+    }
+    document.body.appendChild(el)
+    var vm = new Vue({
+      el: el,
+      attached: log(0),
+      ready: log(1),
+      detached: log(2),
+      template: '<div><test></test><test></test></div>',
+      components: {
+        test: {
+          template: '<span>hi</span>',
+          attached: log(3),
+          ready: log(4),
+          detached: log(5)
+        }
+      }
+    })
+    expect(vm.$el.innerHTML).toBe('<span>hi</span><span>hi</span>')
+    expect(logs.join()).toBe('0,3,4,3,4,1')
+    logs = []
+    vm.$destroy(true)
+    expect(logs.join()).toBe('2,5,5')
+    Vue.options.replace = false
+  })
+
 })