Skip to content

Commit 3df6343

Browse files
author
Evan You
committed
v-if refactor + change to use childVM
1 parent 775948d commit 3df6343

File tree

8 files changed

+208
-256
lines changed

8 files changed

+208
-256
lines changed

src/compiler.js

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ var Emitter = require('./emitter'),
2727
// list of priority directives
2828
// that needs to be checked in specific order
2929
priorityDirectives = [
30-
//'if',
30+
'if',
3131
'repeat',
3232
'view',
3333
'component'
@@ -368,14 +368,18 @@ CompilerProto.compile = function (node, root) {
368368
*/
369369
CompilerProto.checkPriorityDir = function (dirname, node, root) {
370370
var expression, directive, Ctor
371-
if (dirname === 'component' && root !== true && (Ctor = this.resolveComponent(node, undefined, true))) {
371+
if (dirname === 'component' && (Ctor = this.resolveComponent(node, undefined, true))) {
372372
directive = Directive.parse(dirname, '', this, node)
373373
directive.Ctor = Ctor
374374
} else {
375375
expression = utils.attr(node, dirname)
376376
directive = expression && Directive.parse(dirname, expression, this, node)
377377
}
378378
if (directive) {
379+
if (root === true) {
380+
utils.warn('Directive v-' + dirname + ' cannot be used on manually instantiated root node.')
381+
return
382+
}
379383
this.deferred.push(directive)
380384
return true
381385
}

src/directives/if.js

Lines changed: 28 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,69 +1,47 @@
1-
var config = require('../config'),
2-
transition = require('../transition')
1+
var utils = require('../utils')
32

43
module.exports = {
54

65
bind: function () {
7-
this.parent = this.el.parentNode || this.el.vue_if_parent
8-
this.ref = document.createComment(config.prefix + '-if-' + this.key)
9-
var detachedRef = this.el.vue_if_ref
10-
if (detachedRef) {
11-
this.parent.insertBefore(this.ref, detachedRef)
6+
7+
this.parent = this.el.parentNode
8+
this.ref = document.createComment('vue-if')
9+
this.Ctor = this.compiler.resolveComponent(this.el)
10+
11+
// insert ref
12+
this.parent.insertBefore(this.ref, this.el)
13+
this.parent.removeChild(this.el)
14+
15+
if (utils.attr(this.el, 'view')) {
16+
utils.warn('Conflict: v-if cannot be used together with v-view')
17+
}
18+
if (utils.attr(this.el, 'repeat')) {
19+
utils.warn('Conflict: v-if cannot be used together with v-repeat')
1220
}
13-
this.el.vue_if_ref = this.ref
1421
},
1522

1623
update: function (value) {
1724

18-
var el = this.el
19-
20-
// sometimes we need to create a VM on a detached node,
21-
// e.g. in v-repeat. In that case, store the desired v-if
22-
// state on the node itself so we can deal with it elsewhere.
23-
el.vue_if = !!value
24-
25-
var parent = this.parent,
26-
ref = this.ref,
27-
compiler = this.compiler
28-
29-
if (!parent) {
30-
if (!el.parentNode) {
31-
return
32-
} else {
33-
parent = this.parent = el.parentNode
34-
}
35-
}
36-
3725
if (!value) {
38-
transition(el, -1, remove, compiler)
39-
} else {
40-
transition(el, 1, insert, compiler)
41-
}
42-
43-
function remove () {
44-
if (!el.parentNode) return
45-
// insert the reference node
46-
var next = el.nextSibling
47-
if (next) {
48-
parent.insertBefore(ref, next)
26+
this._unbind()
27+
} else if (!this.childVM) {
28+
this.childVM = new this.Ctor({
29+
el: this.el.cloneNode(true),
30+
parent: this.vm
31+
})
32+
if (this.compiler.init) {
33+
this.parent.insertBefore(this.childVM.$el, this.ref)
4934
} else {
50-
parent.appendChild(ref)
35+
this.childVM.$before(this.ref)
5136
}
52-
parent.removeChild(el)
53-
}
54-
55-
function insert () {
56-
if (el.parentNode) return
57-
parent.insertBefore(el, ref)
58-
parent.removeChild(ref)
5937
}
38+
6039
},
6140

6241
unbind: function () {
63-
this.el.vue_if_ref = this.el.vue_if_parent = null
64-
var ref = this.ref
65-
if (ref.parentNode) {
66-
ref.parentNode.removeChild(ref)
42+
if (this.childVM) {
43+
this.childVM.$destroy()
44+
this.childVM = null
6745
}
6846
}
6947
}

src/directives/index.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,15 +18,15 @@ module.exports = {
1818
isLiteral: true,
1919
bind: function () {
2020
if (!this.el.vue_vm) {
21-
this.component = new this.Ctor({
21+
this.childVM = new this.Ctor({
2222
el: this.el,
2323
parent: this.vm
2424
})
2525
}
2626
},
2727
unbind: function () {
28-
if (this.component) {
29-
this.component.$destroy()
28+
if (this.childVM) {
29+
this.childVM.$destroy()
3030
}
3131
}
3232
},

src/directives/repeat.js

Lines changed: 11 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -200,12 +200,6 @@ module.exports = {
200200
var ref = vms.length > index
201201
? vms[index].$el
202202
: self.ref
203-
204-
// if reference VM is detached by v-if,
205-
// use its v-if ref node instead
206-
if (!ref.parentNode) {
207-
ref = ref.vue_if_ref
208-
}
209203

210204
// check if data already exists in the old array
211205
oldIndex = self.oldVMs ? indexOf(self.oldVMs, data) : -1
@@ -225,10 +219,6 @@ module.exports = {
225219

226220
// first clone the template node
227221
el = self.el.cloneNode(true)
228-
// then we provide the parentNode for v-if
229-
// so that it can still work in a detached state
230-
el.vue_if_parent = ctn
231-
el.vue_if_ref = ref
232222

233223
// we have an alias, wrap the data
234224
if (self.arg) {
@@ -277,22 +267,18 @@ module.exports = {
277267
// Finally, DOM operations...
278268
el = item.$el
279269
if (existing) {
280-
// we simplify need to re-insert the existing node
281-
// to its new position. However, it can possibly be
282-
// detached by v-if. in that case we insert its v-if
283-
// ref node instead.
284-
ctn.insertBefore(el.parentNode ? el : el.vue_if_ref, ref)
270+
// existing vm, we simplify need to re-insert
271+
// its element to the new position.
272+
ctn.insertBefore(el, ref)
285273
} else {
286-
if (el.vue_if !== false) {
287-
if (self.compiler.init) {
288-
// do not transition on initial compile,
289-
// just manually insert.
290-
ctn.insertBefore(el, ref)
291-
item.$compiler.execHook('attached')
292-
} else {
293-
// give it some nice transition.
294-
item.$before(ref)
295-
}
274+
if (self.compiler.init) {
275+
// do not transition on initial compile,
276+
// just manually insert.
277+
ctn.insertBefore(el, ref)
278+
item.$compiler.execHook('attached')
279+
} else {
280+
// give it some nice transition.
281+
item.$before(ref)
296282
}
297283
}
298284
},

src/directives/view.js

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,7 @@ module.exports = {
2121

2222
update: function(value) {
2323

24-
if (this.childVM) {
25-
this.childVM.$destroy()
26-
}
24+
this._unbind()
2725

2826
var Ctor = this.compiler.getOption('components', value)
2927
if (!Ctor) return

test/functional/fixtures/transition.html

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -34,14 +34,6 @@
3434
<button class="pop" v-on="click:pop">pop</button>
3535
<button class="splice" v-on="click:splice">splice</button>
3636
</div>
37-
<div
38-
class="test"
39-
v-repeat="items"
40-
v-if="filter(this)"
41-
v-transition
42-
v-attr="data-id:a">
43-
{{a}}
44-
</div>
4537
<div
4638
class="test"
4739
v-repeat="items"
@@ -50,6 +42,7 @@
5042
v-attr="data-id:a">
5143
{{a}}
5244
</div>
45+
<div class="test if" v-transition v-if="items.length > 1">This is only visible when item.length > 1</div>
5346
</div>
5447
<h1 style="margin:0">123</h1>
5548

test/functional/specs/transition.js

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,64 +1,60 @@
1-
casper.test.begin('CSS Transition', 25, function (test) {
1+
casper.test.begin('CSS Transition', 20, function (test) {
22

33
var minWait = 50,
44
transDuration = 200
55

66
casper
77
.start('./fixtures/transition.html', function () {
88
test.assertElementCount('.test', 3)
9+
test.assertVisible('.test.if')
910
test.assertNotVisible('.test[data-id="1"]')
1011
})
1112
.thenClick('.button-0')
1213
.wait(minWait, function () {
13-
test.assertElementCount('.test', 4)
1414
test.assertVisible('.test[data-id="1"]')
1515
})
1616
.thenClick('.button-1')
1717
.wait(minWait, function () {
18-
test.assertElementCount('.test', 4)
19-
test.assertElementCount('.test.v-leave', 2)
18+
test.assertElementCount('.test.v-leave', 1)
2019
})
2120
.wait(transDuration, function () {
22-
test.assertElementCount('.test', 3)
2321
test.assertElementCount('.test.v-leave', 0)
2422
test.assertNotVisible('.test[data-id="1"]')
2523
})
2624
.thenClick('.button-2')
2725
.wait(minWait, function () {
28-
test.assertElementCount('.test', 3)
29-
test.assertElementCount('.test.v-leave', 2)
26+
test.assertElementCount('.test.v-leave', 1)
3027
})
3128
.wait(transDuration, function () {
32-
test.assertElementCount('.test', 2)
29+
test.assertElementCount('.test.v-leave', 0)
3330
test.assertNotVisible('.test[data-id="1"]')
3431
test.assertNotVisible('.test[data-id="2"]')
3532
})
3633
.thenClick('.push')
3734
.wait(minWait, function () {
38-
test.assertElementCount('.test', 4)
3935
test.assertVisible('.test[data-id="3"]')
4036
})
4137
.thenClick('.pop')
38+
.thenClick('.pop')
4239
.wait(minWait, function () {
43-
test.assertElementCount('.test', 4)
4440
test.assertElementCount('.test.v-leave', 2)
4541
})
4642
.wait(transDuration, function () {
47-
test.assertElementCount('.test', 2)
43+
test.assertNotVisible('.test.if')
4844
test.assertNotVisible('.test[data-id="1"]')
4945
test.assertNotVisible('.test[data-id="2"]')
5046
})
5147
.thenClick('.splice')
5248
.wait(minWait, function () {
53-
test.assertElementCount('.test', 3)
5449
test.assertVisible('.test[data-id="99"]')
5550
})
5651
// test Array swapping with transition
5752
.thenEvaluate(function () {
5853
test.items = [test.items[1], {a:3}]
5954
})
60-
.wait(transDuration + minWait, function () {
61-
test.assertElementCount('.test', 3)
55+
.wait(minWait, function () {
56+
test.assertVisible('.test.if')
57+
test.assertVisible('.test[data-id="99"]')
6258
test.assertVisible('.test[data-id="3"]')
6359
})
6460
.run(function () {

0 commit comments

Comments
 (0)