Skip to content

Commit 70d5280

Browse files
committed
remove v-component
1 parent ee2b99e commit 70d5280

19 files changed

+195
-237
lines changed

examples/svg/index.html

+6-4
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,11 @@
1010

1111
<!-- template for the polygraph component. -->
1212
<script type="text/x-template" id="polygraph-template">
13-
<polygon v-attr="points:points"></polygon>
14-
<circle cx="100" cy="100" r="80"></circle>
15-
<text v-repeat="stats" v-component="axis-label"></text>
13+
<g>
14+
<polygon v-attr="points:points"></polygon>
15+
<circle cx="100" cy="100" r="80"></circle>
16+
<axis-label v-repeat="stats"></axis-label>
17+
</g>
1618
</script>
1719

1820
<!-- template for the axis label component. -->
@@ -24,7 +26,7 @@
2426
<div id="demo">
2527
<!-- Use the component -->
2628
<svg width="200" height="200">
27-
<g v-component="polygraph" stats="{{stats}}"></g>
29+
<polygraph stats="{{stats}}"></polygraph>
2830
</svg>
2931
<!-- controls -->
3032
<div v-repeat="stats">

examples/svg/svg.js

+1
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ var stats = [
1212
Vue.component('polygraph', {
1313
props: ['stats'],
1414
template: '#polygraph-template',
15+
replace: true,
1516
computed: {
1617
// a computed property for the polygon's points
1718
points: function () {

examples/tree/index.html

+15-15
Original file line numberDiff line numberDiff line change
@@ -26,28 +26,28 @@
2626

2727
<!-- item template -->
2828
<script type="text/x-template" id="item-template">
29-
<div v-class="bold: isFolder"
30-
v-on="click: toggle, dblclick: changeType">
31-
{{model.name}}
32-
<span v-if="isFolder">[{{open ? '-' : '+'}}]</span>
33-
</div>
34-
<ul v-show="open" v-if="isFolder">
35-
<li class="item"
36-
v-repeat="model: model.children"
37-
v-component="item">
38-
</li>
39-
<li v-on="click: addChild">+</li>
40-
</ul>
29+
<li>
30+
<div v-class="bold: isFolder"
31+
v-on="click: toggle, dblclick: changeType">
32+
{{model.name}}
33+
<span v-if="isFolder">[{{open ? '-' : '+'}}]</span>
34+
</div>
35+
<ul v-show="open" v-if="isFolder">
36+
<item class="item"
37+
v-repeat="model: model.children">
38+
</item>
39+
<li v-on="click: addChild">+</li>
40+
</ul>
41+
</li>
4142
</script>
4243

4344
<p>(You can double click on an item to turn it into a folder.)</p>
4445

4546
<!-- the demo root element -->
4647
<ul id="demo">
47-
<li class="item"
48-
v-component="item"
48+
<item class="item"
4949
model="{{treeData}}">
50-
</li>
50+
</item>
5151
</ul>
5252

5353
<!-- demo code -->

examples/tree/tree.js

+1
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ var data = {
3232
Vue.component('item', {
3333
props: ['model'],
3434
template: '#item-template',
35+
replace: true,
3536
data: function () {
3637
return {
3738
open: false

src/compiler/compile.js

+35-18
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ var templateParser = require('../parsers/template')
66

77
// internal directives
88
var propDef = require('../directives/prop')
9-
// var componentDef = require('../directives/component')
9+
var componentDef = require('../directives/component')
1010

1111
module.exports = compile
1212

@@ -192,24 +192,19 @@ function compileElement (el, options) {
192192
}
193193
return compile(el, options._parent.$options, true, true)
194194
}
195-
var linkFn, tag, component
196-
// check custom element component, but only on non-root
197-
if (!el.__vue__) {
198-
tag = el.tagName.toLowerCase()
199-
component =
200-
tag.indexOf('-') > 0 &&
201-
options.components[tag]
202-
if (component) {
203-
el.setAttribute(config.prefix + 'component', tag)
204-
}
205-
}
206-
if (component || el.hasAttributes()) {
207-
// check terminal direcitves
195+
var linkFn
196+
var hasAttrs = el.hasAttributes()
197+
// check terminal direcitves (repeat & if)
198+
if (hasAttrs) {
208199
linkFn = checkTerminalDirectives(el, options)
209-
// if not terminal, build normal link function
210-
if (!linkFn) {
211-
linkFn = compileDirectives(el, options)
212-
}
200+
}
201+
// check component
202+
if (!linkFn) {
203+
linkFn = checkComponent(el, options)
204+
}
205+
// normal directives
206+
if (!linkFn && hasAttrs) {
207+
linkFn = compileDirectives(el, options)
213208
}
214209
// if the element is a textarea, we need to interpolate
215210
// its content on initial render.
@@ -449,6 +444,28 @@ function makePropsLinkFn (props) {
449444
}
450445
}
451446

447+
/**
448+
* Check if an element is a component. If yes, return
449+
* a component link function.
450+
*
451+
* @param {Element} el
452+
* @param {Object} options
453+
* @return {Function|undefined}
454+
*/
455+
456+
function checkComponent (el, options) {
457+
var componentId = _.checkComponent(el, options)
458+
if (componentId) {
459+
var componentLinkFn = function (vm, el, host) {
460+
vm._bindDir('component', el, {
461+
expression: componentId
462+
}, componentDef, host)
463+
}
464+
componentLinkFn.terminal = true
465+
return componentLinkFn
466+
}
467+
}
468+
452469
/**
453470
* Check an element for terminal directives in fixed order.
454471
* If it finds one, return a terminal link function.

src/compiler/transclude.js

+3-3
Original file line numberDiff line numberDiff line change
@@ -73,18 +73,19 @@ function transcludeTemplate (el, options) {
7373
_.warn('Invalid template option: ' + template)
7474
} else {
7575
var rawContent = options._content || _.extractContent(el)
76+
var replacer = frag.firstChild
7677
if (options.replace) {
7778
if (
7879
frag.childNodes.length > 1 ||
80+
replacer.nodeType !== 1 ||
7981
// when root node has v-repeat, the instance ends up
8082
// having multiple top-level nodes, thus becoming a
8183
// block instance. (#835)
82-
frag.firstChild.hasAttribute(config.prefix + 'repeat')
84+
replacer.hasAttribute(config.prefix + 'repeat')
8385
) {
8486
transcludeContent(frag, rawContent)
8587
return frag
8688
} else {
87-
var replacer = frag.firstChild
8889
options._replacerAttrs = extractAttrs(replacer)
8990
mergeAttrs(el, replacer)
9091
transcludeContent(replacer, rawContent)
@@ -199,7 +200,6 @@ function insertContentAt (outlet, contents) {
199200

200201
function extractAttrs (el) {
201202
var attrs = el.attributes
202-
if (!attrs) return
203203
var res = {}
204204
var i = attrs.length
205205
while (i--) {

src/config.js

+1-2
Original file line numberDiff line numberDiff line change
@@ -71,8 +71,7 @@ module.exports = {
7171

7272
_terminalDirectives: [
7373
'repeat',
74-
'if',
75-
'component'
74+
'if'
7675
]
7776

7877
}

src/directives/index.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -23,5 +23,5 @@ exports.events = require('./events')
2323

2424
// internal directives that should not be used directly
2525
// but we still want to expose them for advanced usage.
26-
exports.component = require('./component')
26+
exports._component = require('./component')
2727
exports._prop = require('./prop')

src/directives/repeat.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -92,8 +92,8 @@ module.exports = {
9292

9393
checkComponent: function () {
9494
this.componentState = UNRESOLVED
95-
var id = _.attr(this.el, 'component')
9695
var options = this.vm.$options
96+
var id = _.checkComponent(this.el, options)
9797
if (!id) {
9898
// default constructor
9999
this.Ctor = _.Vue

src/util/index.js

+23-1
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,26 @@ extend(exports, lang)
55
extend(exports, require('./env'))
66
extend(exports, require('./dom'))
77
extend(exports, require('./filter'))
8-
extend(exports, require('./debug'))
8+
extend(exports, require('./debug'))
9+
10+
/**
11+
* Check if an element is a component, if yes return its
12+
* component id.
13+
*
14+
* @param {Element} el
15+
* @param {Object} options
16+
* @return {String|undefined}
17+
*/
18+
19+
exports.checkComponent = function (el, options) {
20+
var tag = el.tagName.toLowerCase()
21+
if (options.components[tag]) {
22+
return tag
23+
}
24+
// dynamic syntax
25+
if (tag === 'component') {
26+
var exp = el.getAttribute('type')
27+
el.removeAttribute('type')
28+
return exp
29+
}
30+
}

test/unit/specs/async_component_spec.js

+12-12
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ describe('Async components', function () {
1919
it('normal', function (done) {
2020
var vm = new Vue({
2121
el: el,
22-
template: '<div v-component="test"></div>',
22+
template: '<test></test>',
2323
components: {
2424
test: function (resolve) {
2525
setTimeout(function () {
@@ -40,7 +40,7 @@ describe('Async components', function () {
4040
it('dynamic', function (done) {
4141
var vm = new Vue({
4242
el: el,
43-
template: '<div v-component="{{view}}"></div>',
43+
template: '<component type="{{view}}"></component>',
4444
data: {
4545
view: 'a'
4646
},
@@ -84,7 +84,7 @@ describe('Async components', function () {
8484
it('invalidate pending on dynamic switch', function (done) {
8585
var vm = new Vue({
8686
el: el,
87-
template: '<div v-component="{{view}}"></div>',
87+
template: '<component type="{{view}}"></component>',
8888
data: {
8989
view: 'a'
9090
},
@@ -124,12 +124,12 @@ describe('Async components', function () {
124124
it('invalidate pending on teardown', function (done) {
125125
var vm = new Vue({
126126
el: el,
127-
template: '<div v-component="a"></div>',
127+
template: '<test></test>',
128128
data: {
129129
view: 'a'
130130
},
131131
components: {
132-
a: function (resolve) {
132+
test: function (resolve) {
133133
setTimeout(function () {
134134
resolve({
135135
template: 'A'
@@ -157,10 +157,10 @@ describe('Async components', function () {
157157
var vm = new Vue({
158158
el: el,
159159
template:
160-
'<div v-component="a"></div>' +
161-
'<div v-component="a"></div>',
160+
'<test></test>' +
161+
'<test></test>',
162162
components: {
163-
a: factory
163+
test: factory
164164
}
165165
})
166166
function factory (resolve) {
@@ -192,7 +192,7 @@ describe('Async components', function () {
192192
it('normal', function (done) {
193193
var vm = new Vue({
194194
el: el,
195-
template: '<div v-repeat="list" v-component="test"></div>',
195+
template: '<test v-repeat="list"></test>',
196196
data: {
197197
list: [1, 2, 3]
198198
},
@@ -216,7 +216,7 @@ describe('Async components', function () {
216216
it('only resolve once', function (done) {
217217
var vm = new Vue({
218218
el: el,
219-
template: '<div v-repeat="list" v-component="test"></div>',
219+
template: '<test v-repeat="list"></test>',
220220
data: {
221221
list: [1, 2, 3]
222222
},
@@ -250,7 +250,7 @@ describe('Async components', function () {
250250
it('invalidate on teardown', function (done) {
251251
var vm = new Vue({
252252
el: el,
253-
template: '<div v-repeat="list" v-component="test"></div>',
253+
template: '<test v-repeat="list"></test>',
254254
data: {
255255
list: [1, 2, 3]
256256
},
@@ -277,7 +277,7 @@ describe('Async components', function () {
277277
it('warn when used with dynamic v-repeat', function () {
278278
var vm = new Vue({
279279
el: el,
280-
template: '<div v-repeat="list" v-component="{{c}}"></div>',
280+
template: '<component v-repeat="list" type="{{c}}"></component>',
281281
data: {
282282
list: [1, 2, 3],
283283
c: 'test'

0 commit comments

Comments
 (0)