Skip to content

Commit 1592a06

Browse files
committed
adjust $destroy procedure so final cleanup happens after transition finishes
1 parent 36673b2 commit 1592a06

File tree

5 files changed

+43
-49
lines changed

5 files changed

+43
-49
lines changed

changes.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,8 @@ By default, all child components **DO NOT** inherit the parent scope. Only anony
197197

198198
- #### renamed hook: `afterDestroy` -> `destroyed`
199199

200+
Additionally, if there is a leaving transition, `beforeDestroy` is called before the transition starts, and `destroyed` will be called **after** the transition has finished (right after `detached`).
201+
200202
## Instance methods change
201203

202204
- #### `vm.$watch`

src/api/lifecycle.js

Lines changed: 35 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -64,10 +64,6 @@ exports.$destroy = function (remove) {
6464
}
6565
this._callHook('beforeDestroy')
6666
this._isBeingDestroyed = true
67-
// remove DOM element
68-
if (remove && this.$el) {
69-
this.$remove()
70-
}
7167
var i
7268
// remove self from parent. only necessary
7369
// if parent is not being destroyed as well.
@@ -93,27 +89,47 @@ exports.$destroy = function (remove) {
9389
for (i in this._userWatchers) {
9490
this._userWatchers[i].teardown()
9591
}
96-
// clean up
92+
// remove reference to self on $el
9793
if (this.$el) {
9894
this.$el.__vue__ = null
9995
}
96+
// remove DOM element
97+
var self = this
98+
if (remove && this.$el) {
99+
this.$remove(function () {
100+
cleanup(self)
101+
})
102+
} else {
103+
cleanup(self)
104+
}
105+
}
106+
107+
/**
108+
* Clean up to ensure garbage collection.
109+
* This is called after the leave transition if there
110+
* is any.
111+
*
112+
* @param {Vue} vm
113+
*/
114+
115+
function cleanup (vm) {
100116
// remove reference from data ob
101-
this._data.__ob__.removeVm(this)
102-
this._data =
103-
this._watchers =
104-
this._userWatchers =
105-
this._watcherList =
106-
this.$el =
107-
this.$parent =
108-
this.$root =
109-
this._children =
110-
this._bindings =
111-
this._directives = null
117+
vm._data.__ob__.removeVm(vm)
118+
vm._data =
119+
vm._watchers =
120+
vm._userWatchers =
121+
vm._watcherList =
122+
vm.$el =
123+
vm.$parent =
124+
vm.$root =
125+
vm._children =
126+
vm._bindings =
127+
vm._directives = null
112128
// call the last hook...
113-
this._isDestroyed = true
114-
this._callHook('destroyed')
129+
vm._isDestroyed = true
130+
vm._callHook('destroyed')
115131
// turn off all instance listeners.
116-
this.$off()
132+
vm.$off()
117133
}
118134

119135
/**

src/directive.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ p._bind = function (def) {
7575
// wrapped updater for context
7676
var dir = this
7777
var update = this._update = function (val, oldVal) {
78-
if (!dir._locked && !dir.vm._isBeingDestroyed) {
78+
if (!dir._locked) {
7979
dir.update(val, oldVal)
8080
}
8181
}

src/directives/component.js

Lines changed: 5 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -117,25 +117,14 @@ module.exports = {
117117
child.$remove()
118118
}
119119
} else {
120+
child.$destroy(remove)
120121
var parentDirs = this.parentDirs
121-
var destroy = function () {
122-
child.$destroy()
123-
if (parentDirs) {
124-
var i = parentDirs.length
125-
while (i--) {
126-
parentDirs[i]._teardown()
127-
}
122+
if (parentDirs) {
123+
var i = parentDirs.length
124+
while (i--) {
125+
parentDirs[i]._teardown()
128126
}
129127
}
130-
if (remove) {
131-
// setting the "being destroyed" flag before
132-
// removing to avoid content being changed during
133-
// transitions
134-
child._isBeingDestroyed = true
135-
child.$remove(destroy)
136-
} else {
137-
destroy()
138-
}
139128
}
140129
this.childVM = null
141130
},

test/unit/specs/directive_spec.js

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -177,17 +177,4 @@ describe('Directive', function () {
177177
})
178178
})
179179

180-
it('avoid update when vm is being destroyed', function (done) {
181-
var d = new Directive('test', el, vm, {
182-
expression: 'a',
183-
}, def)
184-
expect(def.update.calls.count()).toBe(1)
185-
vm._isBeingDestroyed = true
186-
vm.a = 2
187-
nextTick(function () {
188-
expect(def.update.calls.count()).toBe(1)
189-
done()
190-
})
191-
})
192-
193180
})

0 commit comments

Comments
 (0)