mirror of https://github.com/vuejs/vue.git
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
This commit is contained in:
parent
bd835ac276
commit
04249e320a
|
|
@ -27,7 +27,7 @@
|
|||
"src/directives/repeat.js",
|
||||
"src/directives/on.js",
|
||||
"src/directives/model.js",
|
||||
"src/directives/component.js"
|
||||
"src/directives/with.js"
|
||||
],
|
||||
"dependencies": {
|
||||
"component/emitter": "*"
|
||||
|
|
|
|||
|
|
@ -226,9 +226,11 @@ CompilerProto.compile = function (node, root) {
|
|||
|
||||
// special attributes to check
|
||||
var repeatExp,
|
||||
componentExp,
|
||||
withKey,
|
||||
partialId,
|
||||
directive
|
||||
directive,
|
||||
componentId = utils.attr(node, 'component') || tagName.toLowerCase(),
|
||||
componentCtor = compiler.getOption('components', componentId)
|
||||
|
||||
// It is important that we access these attributes
|
||||
// procedurally because the order matters.
|
||||
|
|
@ -244,21 +246,16 @@ CompilerProto.compile = function (node, root) {
|
|||
// repeat block cannot have v-id at the same time.
|
||||
directive = Directive.parse('repeat', repeatExp, compiler, node)
|
||||
if (directive) {
|
||||
directive.Ctor = componentCtor
|
||||
compiler.bindDirective(directive)
|
||||
}
|
||||
|
||||
// v-component has 2nd highest priority
|
||||
} else if (!root && (componentExp = utils.attr(node, 'component'))) {
|
||||
// v-with has 2nd highest priority
|
||||
} else if (!root && ((withKey = utils.attr(node, 'with')) || componentCtor)) {
|
||||
|
||||
directive = Directive.parse('component', componentExp, compiler, node)
|
||||
directive = Directive.parse('with', withKey || '', compiler, node)
|
||||
if (directive) {
|
||||
// component directive is a bit different from the others.
|
||||
// when it has no argument, it should be treated as a
|
||||
// simple directive with its key as the argument.
|
||||
if (componentExp.indexOf(':') === -1) {
|
||||
directive.isSimple = true
|
||||
directive.arg = directive.key
|
||||
}
|
||||
directive.Ctor = componentCtor
|
||||
compiler.bindDirective(directive)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ var prefix = 'v',
|
|||
'text',
|
||||
'repeat',
|
||||
'partial',
|
||||
'with',
|
||||
'component',
|
||||
'component-id',
|
||||
'transition'
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ module.exports = {
|
|||
repeat : require('./repeat'),
|
||||
model : require('./model'),
|
||||
'if' : require('./if'),
|
||||
component : require('./component'),
|
||||
'with' : require('./with'),
|
||||
|
||||
attr: function (value) {
|
||||
this.el.setAttribute(this.arg, value)
|
||||
|
|
|
|||
|
|
@ -90,9 +90,8 @@ module.exports = {
|
|||
ctn = self.container = el.parentNode
|
||||
|
||||
// extract child VM information, if any
|
||||
ViewModel = ViewModel || require('../viewmodel')
|
||||
var componentId = utils.attr(el, 'component')
|
||||
self.ChildVM = self.compiler.getOption('components', componentId) || ViewModel
|
||||
ViewModel = ViewModel || require('../viewmodel')
|
||||
self.Ctor = self.Ctor || ViewModel
|
||||
|
||||
// extract transition information
|
||||
self.hasTrans = el.hasAttribute(config.attrs.transition)
|
||||
|
|
@ -169,7 +168,7 @@ module.exports = {
|
|||
}, this.compiler)
|
||||
}
|
||||
|
||||
item = new this.ChildVM({
|
||||
item = new this.Ctor({
|
||||
el: node,
|
||||
data: data,
|
||||
compilerOptions: {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
var utils = require('../utils')
|
||||
var ViewModel
|
||||
|
||||
module.exports = {
|
||||
|
||||
|
|
@ -17,16 +17,15 @@ module.exports = {
|
|||
},
|
||||
|
||||
build: function (value) {
|
||||
var Ctor = this.compiler.getOption('components', this.arg)
|
||||
if (!Ctor) utils.warn('unknown component: ' + this.arg)
|
||||
var options = {
|
||||
ViewModel = ViewModel || require('../viewmodel')
|
||||
var Ctor = this.Ctor || ViewModel
|
||||
this.component = new Ctor({
|
||||
el: this.el,
|
||||
data: value,
|
||||
compilerOptions: {
|
||||
parentCompiler: this.compiler
|
||||
}
|
||||
}
|
||||
this.component = new Ctor(options)
|
||||
})
|
||||
},
|
||||
|
||||
unbind: function () {
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>Component</title>
|
||||
<meta charset="utf-8">
|
||||
</head>
|
||||
<body>
|
||||
<div id="test">
|
||||
<!-- v-component + v-with -->
|
||||
<div id="component-and-with" v-component="avatar" v-with="user"></div>
|
||||
|
||||
<!-- custom element + v-with -->
|
||||
<avatar id="element-and-with" v-with="user"></avatar>
|
||||
|
||||
<!-- v-with alone -->
|
||||
<div id="with" v-with="user">{{hi}} {{name}}</div>
|
||||
|
||||
<!-- v-component alone -->
|
||||
<div id="component" v-component="simple"></div>
|
||||
|
||||
<!-- custom element alone -->
|
||||
<simple id="element"></simple>
|
||||
</div>
|
||||
<script src="../../../dist/vue.js"></script>
|
||||
<script>
|
||||
|
||||
Vue.config({debug: true})
|
||||
|
||||
Vue.component('avatar', {
|
||||
template: '{{hi}} {{name}}',
|
||||
ready: function () {
|
||||
console.log(JSON.stringify(this))
|
||||
}
|
||||
})
|
||||
|
||||
Vue.component('simple', {
|
||||
template: '{{hi}} {{user.name}}'
|
||||
})
|
||||
|
||||
var app = new Vue({
|
||||
el: '#test',
|
||||
data: {
|
||||
hi: '123',
|
||||
user: {
|
||||
name: 'Jack'
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -12,7 +12,7 @@
|
|||
<div class="filter">{{filterMsg | nodigits}}</div>
|
||||
<div class="partial" v-partial="partial-test"></div>
|
||||
<div class="vm" v-component="vm-test">{{vmMsg}}</div>
|
||||
<div class="vm-w-model" v-component="vm-w-model:vmData">{{selfMsg + msg}}</div>
|
||||
<div class="vm-w-model" v-component="vm-w-model" v-with="vmData">{{selfMsg + msg}}</div>
|
||||
</div>
|
||||
<div id="child">
|
||||
<div class="cvm" v-component="vm-test">{{vmMsg}}</div>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,17 @@
|
|||
casper.test.begin('Components', 5, function (test) {
|
||||
|
||||
casper
|
||||
.start('./fixtures/component.html')
|
||||
.then(function () {
|
||||
var expected = '123 Jack'
|
||||
test.assertSelectorHasText('#component-and-with', expected)
|
||||
test.assertSelectorHasText('#element-and-with', expected)
|
||||
test.assertSelectorHasText('#component', expected)
|
||||
test.assertSelectorHasText('#with', expected)
|
||||
test.assertSelectorHasText('#element', expected)
|
||||
})
|
||||
.run(function () {
|
||||
test.done()
|
||||
})
|
||||
|
||||
})
|
||||
|
|
@ -511,7 +511,7 @@ describe('UNIT: Directives', function () {
|
|||
|
||||
describe('component', function () {
|
||||
|
||||
it('should work with no args', function () {
|
||||
it('should create a child viewmodel with given constructor', function () {
|
||||
var testId = 'component-test'
|
||||
mock(testId, '<div v-component="' + testId + '"></div>')
|
||||
var t = new Vue({
|
||||
|
|
@ -528,25 +528,22 @@ describe('UNIT: Directives', function () {
|
|||
assert.strictEqual(t.$el.querySelector('span').textContent, '123')
|
||||
})
|
||||
|
||||
it('should work with arg (passed-in model from parent)', function () {
|
||||
var testId = 'component-test-2'
|
||||
mock(testId, '<div v-component="' + testId + ':options.test"></div>')
|
||||
})
|
||||
|
||||
describe('with', function () {
|
||||
|
||||
it('should create a child viewmodel with given data', function () {
|
||||
var testId = 'with-test'
|
||||
mock(testId, '<span v-with="test">{{msg}}</span>')
|
||||
var t = new Vue({
|
||||
el: '#' + testId,
|
||||
data: {
|
||||
options: {
|
||||
test: {
|
||||
msg: '123'
|
||||
}
|
||||
}
|
||||
},
|
||||
components: {
|
||||
'component-test-2': {
|
||||
template: '<span>{{msg}}</span>'
|
||||
test: {
|
||||
msg: testId
|
||||
}
|
||||
}
|
||||
})
|
||||
assert.strictEqual(t.$el.querySelector('span').textContent, '123')
|
||||
assert.strictEqual(t.$el.querySelector('span').textContent, testId)
|
||||
})
|
||||
|
||||
})
|
||||
|
|
|
|||
Loading…
Reference in New Issue