Skip to content

Commit 0b0d374

Browse files
author
kingwl
committed
fix the wrong orders of call 'detached' and 'destroyed' hook
1 parent 2c64dae commit 0b0d374

File tree

2 files changed

+59
-7
lines changed

2 files changed

+59
-7
lines changed

src/fragment/fragment.js

+17-7
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,7 @@ function multiRemove () {
144144
}
145145
self.destroy()
146146
})
147+
this.afterRemove()
147148
}
148149

149150
/**
@@ -157,6 +158,22 @@ Fragment.prototype.beforeRemove = function () {
157158
// fragments, depth-first
158159
this.childFrags[i].beforeRemove(false)
159160
}
161+
162+
var dirs = this.unlink.dirs
163+
for (i = 0, l = dirs.length; i < l; i++) {
164+
// disable the watchers on all the directives
165+
// so that the rendered content stays the same
166+
// during removal.
167+
dirs[i]._watcher && dirs[i]._watcher.teardown()
168+
}
169+
}
170+
171+
/**
172+
* ensure destroyed after detached.
173+
*/
174+
175+
Fragment.prototype.afterRemove = function () {
176+
var i, l
160177
for (i = 0, l = this.children.length; i < l; i++) {
161178
// Call destroy for all contained instances,
162179
// with remove:false and defer:true.
@@ -165,13 +182,6 @@ Fragment.prototype.beforeRemove = function () {
165182
// on them.
166183
this.children[i].$destroy(false, true)
167184
}
168-
var dirs = this.unlink.dirs
169-
for (i = 0, l = dirs.length; i < l; i++) {
170-
// disable the watchers on all the directives
171-
// so that the rendered content stays the same
172-
// during removal.
173-
dirs[i]._watcher && dirs[i]._watcher.teardown()
174-
}
175185
}
176186

177187
/**

test/unit/specs/instance/events_spec.js

+42
Original file line numberDiff line numberDiff line change
@@ -315,6 +315,48 @@ describe('Instance Events', function () {
315315
expect(spy2.calls.count()).toBe(2)
316316
})
317317

318+
// Github issues #3870
319+
it('detached then destroyed', function (done) {
320+
var el = document.createElement('div')
321+
document.body.appendChild(el) // for inDoc.
322+
var vm = new Vue({
323+
el: el,
324+
template: '<div><mod v-if="show"></mod></div>',
325+
data: {
326+
show: false
327+
},
328+
components: {
329+
mod: {
330+
template: '<div><comp></comp></div>',
331+
components: {
332+
comp: {
333+
template: '<div>123</div>',
334+
detached: function () {
335+
spy()
336+
expect(spy2).not.toHaveBeenCalled()
337+
},
338+
destroyed: function () {
339+
spy2()
340+
expect(spy).toHaveBeenCalled()
341+
}
342+
}
343+
}
344+
}
345+
}
346+
})
347+
_.nextTick(function () {
348+
vm.show = true
349+
_.nextTick(function () {
350+
vm.show = false
351+
_.nextTick(function () {
352+
expect(spy).toHaveBeenCalled()
353+
expect(spy2).toHaveBeenCalled()
354+
done()
355+
})
356+
})
357+
})
358+
})
359+
318360
it('should not fire on detached child', function () {
319361
var el = document.createElement('div')
320362
var childEl = document.createElement('div')

0 commit comments

Comments
 (0)