Skip to content

Commit 4a8581f

Browse files
committed
do not defer cleanup when unbinding component (fix vuejs#1006)
1 parent d07bcce commit 4a8581f

File tree

2 files changed

+39
-10
lines changed

2 files changed

+39
-10
lines changed

src/directives/component.js

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -101,12 +101,12 @@ module.exports = {
101101
this.invalidatePending()
102102
if (!value) {
103103
// just remove current
104-
this.unbuild()
104+
this.unbuild(true)
105105
this.remove(this.childVM, afterTransition)
106106
this.unsetCurrent()
107107
} else {
108108
this.resolveCtor(value, _.bind(function () {
109-
this.unbuild()
109+
this.unbuild(true)
110110
var newComponent = this.build(data)
111111
/* istanbul ignore if */
112112
if (afterBuild) afterBuild(newComponent)
@@ -190,17 +190,19 @@ module.exports = {
190190
/**
191191
* Teardown the current child, but defers cleanup so
192192
* that we can separate the destroy and removal steps.
193+
*
194+
* @param {Boolean} defer
193195
*/
194196

195-
unbuild: function () {
197+
unbuild: function (defer) {
196198
var child = this.childVM
197199
if (!child || this.keepAlive) {
198200
return
199201
}
200202
// the sole purpose of `deferCleanup` is so that we can
201203
// "deactivate" the vm right now and perform DOM removal
202204
// later.
203-
child.$destroy(false, true)
205+
child.$destroy(false, defer)
204206
},
205207

206208
/**
@@ -285,6 +287,7 @@ module.exports = {
285287

286288
unbind: function () {
287289
this.invalidatePending()
290+
// Do not defer cleanup when unbinding
288291
this.unbuild()
289292
this.unsetCurrent()
290293
// destroy all keep-alive cached instances

test/unit/specs/misc_spec.js

Lines changed: 32 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ describe('Misc', function () {
8181
})
8282

8383
// #1005
84-
it('call attach/ready/detach hook for child components', function () {
84+
it('call lifecycle hooks for child components', function () {
8585
Vue.options.replace = true
8686
var el = document.createElement('div')
8787
var logs = []
@@ -96,22 +96,48 @@ describe('Misc', function () {
9696
attached: log(0),
9797
ready: log(1),
9898
detached: log(2),
99+
beforeDestroy: log(3),
100+
destroyed: log(4),
99101
template: '<div><test></test><test></test></div>',
100102
components: {
101103
test: {
102104
template: '<span>hi</span>',
103-
attached: log(3),
104-
ready: log(4),
105-
detached: log(5)
105+
attached: log(5),
106+
ready: log(6),
107+
detached: log(7),
108+
beforeDestroy: log(8),
109+
destroyed: log(9)
106110
}
107111
}
108112
})
109113
expect(vm.$el.innerHTML).toBe('<span>hi</span><span>hi</span>')
110-
expect(logs.join()).toBe('0,3,4,3,4,1')
114+
expect(logs.join()).toBe('0,5,6,5,6,1')
111115
logs = []
112116
vm.$destroy(true)
113-
expect(logs.join()).toBe('2,5,5')
117+
expect(logs.join()).toBe('3,8,9,8,9,2,7,7,4')
114118
Vue.options.replace = false
115119
})
116120

121+
// #1006
122+
it('destroyed hook for components inside v-if', function (done) {
123+
var spy = jasmine.createSpy('v-if destroyed hook')
124+
var vm = new Vue({
125+
el: document.createElement('div'),
126+
template: '<template v-if="ok"><test></test></template>',
127+
data: {
128+
ok: true
129+
},
130+
components: {
131+
test: {
132+
destroyed: spy
133+
}
134+
}
135+
})
136+
vm.ok = false
137+
Vue.nextTick(function () {
138+
expect(spy).toHaveBeenCalled()
139+
done()
140+
})
141+
})
142+
117143
})

0 commit comments

Comments
 (0)