Skip to content

Commit 84a2c70

Browse files
committed
properly clean up child when switching before wait-for fires (fix vuejs#1152)
1 parent 8600d8a commit 84a2c70

File tree

2 files changed

+57
-3
lines changed

2 files changed

+57
-3
lines changed

src/directives/component.js

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -117,22 +117,29 @@ module.exports = {
117117
} else {
118118
this.resolveComponent(value, _.bind(function () {
119119
this.unbuild(true)
120+
if (this.waitingFor) {
121+
this.waitingFor.$destroy()
122+
this.waitingFor = null
123+
}
120124
var options
121125
var self = this
122126
var waitFor = this.waitForEvent
123127
if (waitFor) {
124128
options = {
125129
created: function () {
126130
this.$once(waitFor, function () {
131+
self.waitingFor = null
127132
self.transition(this, cb)
128133
})
129134
}
130135
}
131136
}
132137
var cached = this.getCached()
133-
var newComponent = cached || this.build(options)
138+
var newComponent = this.build(options)
134139
if (!waitFor || cached) {
135140
this.transition(newComponent, cb)
141+
} else {
142+
this.waitingFor = newComponent
136143
}
137144
}, this))
138145
}
@@ -273,7 +280,6 @@ module.exports = {
273280
transition: function (target, cb) {
274281
var self = this
275282
var current = this.childVM
276-
this.unsetCurrent()
277283
this.setCurrent(target)
278284
switch (self.transMode) {
279285
case 'in-out':
@@ -297,6 +303,7 @@ module.exports = {
297303
*/
298304

299305
setCurrent: function (child) {
306+
this.unsetCurrent()
300307
this.childVM = child
301308
var refID = child._refID || this.refID
302309
if (refID) {

test/unit/specs/directives/component_spec.js

Lines changed: 48 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -312,13 +312,60 @@ if (_.inBrowser) {
312312
}
313313
})
314314
vm.$children[0].$emit('ok')
315+
expect(el.textContent).toBe('AAA')
315316
vm.view = 'view-b'
316317
_.nextTick(function () {
317318
expect(el.textContent).toBe('AAA')
318319
// old vm is already removed, this is the new vm
320+
expect(vm.$children.length).toBe(1)
319321
vm.$children[0].$emit('ok')
320322
expect(el.textContent).toBe('BBB')
321-
done()
323+
// ensure switching before ready event correctly
324+
// cleans up the component being waited on.
325+
// see #1152
326+
vm.view = 'view-a'
327+
_.nextTick(function () {
328+
vm.view = 'view-b'
329+
_.nextTick(function () {
330+
expect(vm.$children.length).toBe(1)
331+
expect(vm.$children[0].$el.textContent).toBe('BBB')
332+
done()
333+
})
334+
})
335+
})
336+
})
337+
338+
// #1150
339+
it('wait-for + keep-alive', function (done) {
340+
var vm = new Vue({
341+
el: el,
342+
data: {
343+
view: 'view-a'
344+
},
345+
template: '<component is="{{view}}" wait-for="ok" keep-alive></component>',
346+
components: {
347+
'view-a': {
348+
template: 'AAA'
349+
},
350+
'view-b': {
351+
template: 'BBB'
352+
}
353+
}
354+
})
355+
vm.$children[0].$emit('ok')
356+
expect(el.textContent).toBe('AAA')
357+
vm.view = 'view-b'
358+
_.nextTick(function () {
359+
expect(vm.$children.length).toBe(2)
360+
vm.$children[1].$emit('ok')
361+
expect(el.textContent).toBe('BBB')
362+
vm.view = 'view-a'
363+
_.nextTick(function () {
364+
// should switch without the need to emit
365+
// because of keep-alive
366+
expect(el.textContent).toBe('AAA')
367+
done()
368+
})
322369
})
323370
})
324371

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy