Skip to content

Commit 04249e3

Browse files
committed
Component Change
- `v-component` now takes only a string value (the component id) - `Vue.component()` now also registers the component id as a custom element - add new directive: `v-with`, which can be used in combination with `v-component` or standalone
1 parent bd835ac commit 04249e3

File tree

10 files changed

+100
-39
lines changed

10 files changed

+100
-39
lines changed

component.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
"src/directives/repeat.js",
2828
"src/directives/on.js",
2929
"src/directives/model.js",
30-
"src/directives/component.js"
30+
"src/directives/with.js"
3131
],
3232
"dependencies": {
3333
"component/emitter": "*"

src/compiler.js

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -226,9 +226,11 @@ CompilerProto.compile = function (node, root) {
226226

227227
// special attributes to check
228228
var repeatExp,
229-
componentExp,
229+
withKey,
230230
partialId,
231-
directive
231+
directive,
232+
componentId = utils.attr(node, 'component') || tagName.toLowerCase(),
233+
componentCtor = compiler.getOption('components', componentId)
232234

233235
// It is important that we access these attributes
234236
// procedurally because the order matters.
@@ -244,21 +246,16 @@ CompilerProto.compile = function (node, root) {
244246
// repeat block cannot have v-id at the same time.
245247
directive = Directive.parse('repeat', repeatExp, compiler, node)
246248
if (directive) {
249+
directive.Ctor = componentCtor
247250
compiler.bindDirective(directive)
248251
}
249252

250-
// v-component has 2nd highest priority
251-
} else if (!root && (componentExp = utils.attr(node, 'component'))) {
253+
// v-with has 2nd highest priority
254+
} else if (!root && ((withKey = utils.attr(node, 'with')) || componentCtor)) {
252255

253-
directive = Directive.parse('component', componentExp, compiler, node)
256+
directive = Directive.parse('with', withKey || '', compiler, node)
254257
if (directive) {
255-
// component directive is a bit different from the others.
256-
// when it has no argument, it should be treated as a
257-
// simple directive with its key as the argument.
258-
if (componentExp.indexOf(':') === -1) {
259-
directive.isSimple = true
260-
directive.arg = directive.key
261-
}
258+
directive.Ctor = componentCtor
262259
compiler.bindDirective(directive)
263260
}
264261

src/config.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ var prefix = 'v',
44
'text',
55
'repeat',
66
'partial',
7+
'with',
78
'component',
89
'component-id',
910
'transition'

src/directives/index.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ module.exports = {
77
repeat : require('./repeat'),
88
model : require('./model'),
99
'if' : require('./if'),
10-
component : require('./component'),
10+
'with' : require('./with'),
1111

1212
attr: function (value) {
1313
this.el.setAttribute(this.arg, value)

src/directives/repeat.js

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -90,9 +90,8 @@ module.exports = {
9090
ctn = self.container = el.parentNode
9191

9292
// extract child VM information, if any
93-
ViewModel = ViewModel || require('../viewmodel')
94-
var componentId = utils.attr(el, 'component')
95-
self.ChildVM = self.compiler.getOption('components', componentId) || ViewModel
93+
ViewModel = ViewModel || require('../viewmodel')
94+
self.Ctor = self.Ctor || ViewModel
9695

9796
// extract transition information
9897
self.hasTrans = el.hasAttribute(config.attrs.transition)
@@ -169,7 +168,7 @@ module.exports = {
169168
}, this.compiler)
170169
}
171170

172-
item = new this.ChildVM({
171+
item = new this.Ctor({
173172
el: node,
174173
data: data,
175174
compilerOptions: {

src/directives/component.js renamed to src/directives/with.js

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
var utils = require('../utils')
1+
var ViewModel
22

33
module.exports = {
44

@@ -17,16 +17,15 @@ module.exports = {
1717
},
1818

1919
build: function (value) {
20-
var Ctor = this.compiler.getOption('components', this.arg)
21-
if (!Ctor) utils.warn('unknown component: ' + this.arg)
22-
var options = {
20+
ViewModel = ViewModel || require('../viewmodel')
21+
var Ctor = this.Ctor || ViewModel
22+
this.component = new Ctor({
2323
el: this.el,
2424
data: value,
2525
compilerOptions: {
2626
parentCompiler: this.compiler
2727
}
28-
}
29-
this.component = new Ctor(options)
28+
})
3029
},
3130

3231
unbind: function () {
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<title>Component</title>
5+
<meta charset="utf-8">
6+
</head>
7+
<body>
8+
<div id="test">
9+
<!-- v-component + v-with -->
10+
<div id="component-and-with" v-component="avatar" v-with="user"></div>
11+
12+
<!-- custom element + v-with -->
13+
<avatar id="element-and-with" v-with="user"></avatar>
14+
15+
<!-- v-with alone -->
16+
<div id="with" v-with="user">{{hi}} {{name}}</div>
17+
18+
<!-- v-component alone -->
19+
<div id="component" v-component="simple"></div>
20+
21+
<!-- custom element alone -->
22+
<simple id="element"></simple>
23+
</div>
24+
<script src="../../../dist/vue.js"></script>
25+
<script>
26+
27+
Vue.config({debug: true})
28+
29+
Vue.component('avatar', {
30+
template: '{{hi}} {{name}}',
31+
ready: function () {
32+
console.log(JSON.stringify(this))
33+
}
34+
})
35+
36+
Vue.component('simple', {
37+
template: '{{hi}} {{user.name}}'
38+
})
39+
40+
var app = new Vue({
41+
el: '#test',
42+
data: {
43+
hi: '123',
44+
user: {
45+
name: 'Jack'
46+
}
47+
}
48+
})
49+
</script>
50+
</body>
51+
</html>

test/functional/fixtures/extend.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
<div class="filter">{{filterMsg | nodigits}}</div>
1313
<div class="partial" v-partial="partial-test"></div>
1414
<div class="vm" v-component="vm-test">{{vmMsg}}</div>
15-
<div class="vm-w-model" v-component="vm-w-model:vmData">{{selfMsg + msg}}</div>
15+
<div class="vm-w-model" v-component="vm-w-model" v-with="vmData">{{selfMsg + msg}}</div>
1616
</div>
1717
<div id="child">
1818
<div class="cvm" v-component="vm-test">{{vmMsg}}</div>

test/functional/specs/component.js

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
casper.test.begin('Components', 5, function (test) {
2+
3+
casper
4+
.start('./fixtures/component.html')
5+
.then(function () {
6+
var expected = '123 Jack'
7+
test.assertSelectorHasText('#component-and-with', expected)
8+
test.assertSelectorHasText('#element-and-with', expected)
9+
test.assertSelectorHasText('#component', expected)
10+
test.assertSelectorHasText('#with', expected)
11+
test.assertSelectorHasText('#element', expected)
12+
})
13+
.run(function () {
14+
test.done()
15+
})
16+
17+
})

test/unit/specs/directives.js

Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -511,7 +511,7 @@ describe('UNIT: Directives', function () {
511511

512512
describe('component', function () {
513513

514-
it('should work with no args', function () {
514+
it('should create a child viewmodel with given constructor', function () {
515515
var testId = 'component-test'
516516
mock(testId, '<div v-component="' + testId + '"></div>')
517517
var t = new Vue({
@@ -528,25 +528,22 @@ describe('UNIT: Directives', function () {
528528
assert.strictEqual(t.$el.querySelector('span').textContent, '123')
529529
})
530530

531-
it('should work with arg (passed-in model from parent)', function () {
532-
var testId = 'component-test-2'
533-
mock(testId, '<div v-component="' + testId + ':options.test"></div>')
531+
})
532+
533+
describe('with', function () {
534+
535+
it('should create a child viewmodel with given data', function () {
536+
var testId = 'with-test'
537+
mock(testId, '<span v-with="test">{{msg}}</span>')
534538
var t = new Vue({
535539
el: '#' + testId,
536540
data: {
537-
options: {
538-
test: {
539-
msg: '123'
540-
}
541-
}
542-
},
543-
components: {
544-
'component-test-2': {
545-
template: '<span>{{msg}}</span>'
541+
test: {
542+
msg: testId
546543
}
547544
}
548545
})
549-
assert.strictEqual(t.$el.querySelector('span').textContent, '123')
546+
assert.strictEqual(t.$el.querySelector('span').textContent, testId)
550547
})
551548

552549
})

0 commit comments

Comments
 (0)