remove v-component

This commit is contained in:
Evan You 2015-05-15 11:48:31 -04:00
parent ee2b99efd7
commit 70d5280faa
19 changed files with 195 additions and 237 deletions

View File

@ -10,9 +10,11 @@
<!-- template for the polygraph component. -->
<script type="text/x-template" id="polygraph-template">
<polygon v-attr="points:points"></polygon>
<circle cx="100" cy="100" r="80"></circle>
<text v-repeat="stats" v-component="axis-label"></text>
<g>
<polygon v-attr="points:points"></polygon>
<circle cx="100" cy="100" r="80"></circle>
<axis-label v-repeat="stats"></axis-label>
</g>
</script>
<!-- template for the axis label component. -->
@ -24,7 +26,7 @@
<div id="demo">
<!-- Use the component -->
<svg width="200" height="200">
<g v-component="polygraph" stats="{{stats}}"></g>
<polygraph stats="{{stats}}"></polygraph>
</svg>
<!-- controls -->
<div v-repeat="stats">

View File

@ -12,6 +12,7 @@ var stats = [
Vue.component('polygraph', {
props: ['stats'],
template: '#polygraph-template',
replace: true,
computed: {
// a computed property for the polygon's points
points: function () {

View File

@ -26,28 +26,28 @@
<!-- item template -->
<script type="text/x-template" id="item-template">
<div v-class="bold: isFolder"
v-on="click: toggle, dblclick: changeType">
{{model.name}}
<span v-if="isFolder">[{{open ? '-' : '+'}}]</span>
</div>
<ul v-show="open" v-if="isFolder">
<li class="item"
v-repeat="model: model.children"
v-component="item">
</li>
<li v-on="click: addChild">+</li>
</ul>
<li>
<div v-class="bold: isFolder"
v-on="click: toggle, dblclick: changeType">
{{model.name}}
<span v-if="isFolder">[{{open ? '-' : '+'}}]</span>
</div>
<ul v-show="open" v-if="isFolder">
<item class="item"
v-repeat="model: model.children">
</item>
<li v-on="click: addChild">+</li>
</ul>
</li>
</script>
<p>(You can double click on an item to turn it into a folder.)</p>
<!-- the demo root element -->
<ul id="demo">
<li class="item"
v-component="item"
<item class="item"
model="{{treeData}}">
</li>
</item>
</ul>
<!-- demo code -->

View File

@ -32,6 +32,7 @@ var data = {
Vue.component('item', {
props: ['model'],
template: '#item-template',
replace: true,
data: function () {
return {
open: false

View File

@ -6,7 +6,7 @@ var templateParser = require('../parsers/template')
// internal directives
var propDef = require('../directives/prop')
// var componentDef = require('../directives/component')
var componentDef = require('../directives/component')
module.exports = compile
@ -192,24 +192,19 @@ function compileElement (el, options) {
}
return compile(el, options._parent.$options, true, true)
}
var linkFn, tag, component
// check custom element component, but only on non-root
if (!el.__vue__) {
tag = el.tagName.toLowerCase()
component =
tag.indexOf('-') > 0 &&
options.components[tag]
if (component) {
el.setAttribute(config.prefix + 'component', tag)
}
}
if (component || el.hasAttributes()) {
// check terminal direcitves
var linkFn
var hasAttrs = el.hasAttributes()
// check terminal direcitves (repeat & if)
if (hasAttrs) {
linkFn = checkTerminalDirectives(el, options)
// if not terminal, build normal link function
if (!linkFn) {
linkFn = compileDirectives(el, options)
}
}
// check component
if (!linkFn) {
linkFn = checkComponent(el, options)
}
// normal directives
if (!linkFn && hasAttrs) {
linkFn = compileDirectives(el, options)
}
// if the element is a textarea, we need to interpolate
// its content on initial render.
@ -449,6 +444,28 @@ function makePropsLinkFn (props) {
}
}
/**
* Check if an element is a component. If yes, return
* a component link function.
*
* @param {Element} el
* @param {Object} options
* @return {Function|undefined}
*/
function checkComponent (el, options) {
var componentId = _.checkComponent(el, options)
if (componentId) {
var componentLinkFn = function (vm, el, host) {
vm._bindDir('component', el, {
expression: componentId
}, componentDef, host)
}
componentLinkFn.terminal = true
return componentLinkFn
}
}
/**
* Check an element for terminal directives in fixed order.
* If it finds one, return a terminal link function.

View File

@ -73,18 +73,19 @@ function transcludeTemplate (el, options) {
_.warn('Invalid template option: ' + template)
} else {
var rawContent = options._content || _.extractContent(el)
var replacer = frag.firstChild
if (options.replace) {
if (
frag.childNodes.length > 1 ||
replacer.nodeType !== 1 ||
// when root node has v-repeat, the instance ends up
// having multiple top-level nodes, thus becoming a
// block instance. (#835)
frag.firstChild.hasAttribute(config.prefix + 'repeat')
replacer.hasAttribute(config.prefix + 'repeat')
) {
transcludeContent(frag, rawContent)
return frag
} else {
var replacer = frag.firstChild
options._replacerAttrs = extractAttrs(replacer)
mergeAttrs(el, replacer)
transcludeContent(replacer, rawContent)
@ -199,7 +200,6 @@ function insertContentAt (outlet, contents) {
function extractAttrs (el) {
var attrs = el.attributes
if (!attrs) return
var res = {}
var i = attrs.length
while (i--) {

View File

@ -71,8 +71,7 @@ module.exports = {
_terminalDirectives: [
'repeat',
'if',
'component'
'if'
]
}

View File

@ -23,5 +23,5 @@ exports.events = require('./events')
// internal directives that should not be used directly
// but we still want to expose them for advanced usage.
exports.component = require('./component')
exports._component = require('./component')
exports._prop = require('./prop')

View File

@ -92,8 +92,8 @@ module.exports = {
checkComponent: function () {
this.componentState = UNRESOLVED
var id = _.attr(this.el, 'component')
var options = this.vm.$options
var id = _.checkComponent(this.el, options)
if (!id) {
// default constructor
this.Ctor = _.Vue

View File

@ -6,3 +6,25 @@ extend(exports, require('./env'))
extend(exports, require('./dom'))
extend(exports, require('./filter'))
extend(exports, require('./debug'))
/**
* Check if an element is a component, if yes return its
* component id.
*
* @param {Element} el
* @param {Object} options
* @return {String|undefined}
*/
exports.checkComponent = function (el, options) {
var tag = el.tagName.toLowerCase()
if (options.components[tag]) {
return tag
}
// dynamic syntax
if (tag === 'component') {
var exp = el.getAttribute('type')
el.removeAttribute('type')
return exp
}
}

View File

@ -19,7 +19,7 @@ describe('Async components', function () {
it('normal', function (done) {
var vm = new Vue({
el: el,
template: '<div v-component="test"></div>',
template: '<test></test>',
components: {
test: function (resolve) {
setTimeout(function () {
@ -40,7 +40,7 @@ describe('Async components', function () {
it('dynamic', function (done) {
var vm = new Vue({
el: el,
template: '<div v-component="{{view}}"></div>',
template: '<component type="{{view}}"></component>',
data: {
view: 'a'
},
@ -84,7 +84,7 @@ describe('Async components', function () {
it('invalidate pending on dynamic switch', function (done) {
var vm = new Vue({
el: el,
template: '<div v-component="{{view}}"></div>',
template: '<component type="{{view}}"></component>',
data: {
view: 'a'
},
@ -124,12 +124,12 @@ describe('Async components', function () {
it('invalidate pending on teardown', function (done) {
var vm = new Vue({
el: el,
template: '<div v-component="a"></div>',
template: '<test></test>',
data: {
view: 'a'
},
components: {
a: function (resolve) {
test: function (resolve) {
setTimeout(function () {
resolve({
template: 'A'
@ -157,10 +157,10 @@ describe('Async components', function () {
var vm = new Vue({
el: el,
template:
'<div v-component="a"></div>' +
'<div v-component="a"></div>',
'<test></test>' +
'<test></test>',
components: {
a: factory
test: factory
}
})
function factory (resolve) {
@ -192,7 +192,7 @@ describe('Async components', function () {
it('normal', function (done) {
var vm = new Vue({
el: el,
template: '<div v-repeat="list" v-component="test"></div>',
template: '<test v-repeat="list"></test>',
data: {
list: [1, 2, 3]
},
@ -216,7 +216,7 @@ describe('Async components', function () {
it('only resolve once', function (done) {
var vm = new Vue({
el: el,
template: '<div v-repeat="list" v-component="test"></div>',
template: '<test v-repeat="list"></test>',
data: {
list: [1, 2, 3]
},
@ -250,7 +250,7 @@ describe('Async components', function () {
it('invalidate on teardown', function (done) {
var vm = new Vue({
el: el,
template: '<div v-repeat="list" v-component="test"></div>',
template: '<test v-repeat="list"></test>',
data: {
list: [1, 2, 3]
},
@ -277,7 +277,7 @@ describe('Async components', function () {
it('warn when used with dynamic v-repeat', function () {
var vm = new Vue({
el: el,
template: '<div v-repeat="list" v-component="{{c}}"></div>',
template: '<component v-repeat="list" type="{{c}}"></component>',
data: {
list: [1, 2, 3],
c: 'test'

View File

@ -126,12 +126,10 @@ if (_.inBrowser) {
}
})
el.innerHTML = '<my-component><div v-a="b"></div></my-component>'
var def = Vue.options.directives.component
var descriptor = dirParser.parse('my-component')[0]
var linker = compile(el, options)
linker(vm, el)
expect(vm._bindDir.calls.count()).toBe(1)
expect(vm._bindDir).toHaveBeenCalledWith('component', el.firstChild, descriptor, def, undefined)
expect(vm._bindDir.calls.argsFor(0)[0]).toBe('component')
expect(_.warn).not.toHaveBeenCalled()
})
@ -244,32 +242,32 @@ if (_.inBrowser) {
vm = new Vue({
el: el,
template:
'<div v-component="a">' +
'<div v-component="b">' +
'<testa>' +
'<testb>' +
'<div v-repeat="list">{{$value}}</div>' +
'</div>' +
'</div>',
'</testb>' +
'</testa>',
data: {
list: [1,2]
},
components: {
a: { template: '<content></content>' },
b: { template: '<content></content>' }
testa: { template: '<content></content>' },
testb: { template: '<content></content>' }
}
})
expect(el.innerHTML).toBe(
'<div><div>' +
'<testa><testb>' +
'<div>1</div><div>2</div><!--v-repeat-->' +
'</div><!--v-component-->' +
'</div><!--v-component-->'
'</testb><!--v-component-->' +
'</testa><!--v-component-->'
)
vm.list.push(3)
_.nextTick(function () {
expect(el.innerHTML).toBe(
'<div><div>' +
'<testa><testb>' +
'<div>1</div><div>2</div><div>3</div><!--v-repeat-->' +
'</div><!--v-component-->' +
'</div><!--v-component-->'
'</testb><!--v-component-->' +
'</testa><!--v-component-->'
)
done()
})
@ -281,12 +279,12 @@ if (_.inBrowser) {
vm = new Vue({
el: el,
template:
'<div v-component="a" class="a" v-on="click:test(1)"></div>',
'<test class="a" v-on="click:test(1)"></test>',
methods: {
test: parentSpy
},
components: {
a: {
test: {
template: '<div class="b" v-on="click:test(2)"></div>',
replace: true,
methods: {
@ -307,7 +305,7 @@ if (_.inBrowser) {
var vm = new Vue({
el: el,
template:
'<div v-component="test">{{test}}</div>',
'<test>{{test}}</test>',
data: {
test: 'parent'
},
@ -330,7 +328,7 @@ if (_.inBrowser) {
el: el,
template:
'<div v-if="ok">' +
'<div v-component="test">{{test}}</div>' +
'<test>{{test}}</test>' +
'</div>',
data: {
test: 'parent',

View File

@ -18,7 +18,7 @@ if (_.inBrowser) {
it('static', function () {
var vm = new Vue({
el: el,
template: '<div v-component="test"></div>',
template: '<test></test>',
components: {
test: {
data: function () {
@ -28,13 +28,13 @@ if (_.inBrowser) {
}
}
})
expect(el.innerHTML).toBe('<div>123</div><!--v-component-->')
expect(el.innerHTML).toBe('<test>123</test><!--v-component-->')
})
it('replace', function () {
var vm = new Vue({
el: el,
template: '<div v-component="test"></div>',
template: '<test></test>',
components: {
test: {
replace: true,
@ -51,7 +51,7 @@ if (_.inBrowser) {
it('inline-template', function () {
var vm = new Vue({
el: el,
template: '<div v-component="test" inline-template>{{a}}</div>',
template: '<test inline-template>{{a}}</test>',
data: {
a: 'parent'
},
@ -64,13 +64,13 @@ if (_.inBrowser) {
}
}
})
expect(el.innerHTML).toBe('<div>child</div><!--v-component-->')
expect(el.innerHTML).toBe('<test>child</test><!--v-component-->')
})
it('block replace', function () {
var vm = new Vue({
el: el,
template: '<div v-component="test"></div>',
template: '<test></test>',
components: {
test: {
replace: true,
@ -87,19 +87,21 @@ if (_.inBrowser) {
it('dynamic', function (done) {
var vm = new Vue({
el: el,
template: '<div v-component="{{view}}" v-attr="view:view"></div>',
template: '<component type="{{view}}" v-attr="view:view"></component>',
data: {
view: 'a'
},
components: {
a: {
template: 'AAA',
template: '<div>AAA</div>',
replace: true,
data: function () {
return { view: 'a' }
}
},
b: {
template: 'BBB',
template: '<div>BBB</div>',
replace: true,
data: function () {
return { view: 'b' }
}
@ -123,18 +125,20 @@ if (_.inBrowser) {
var spyB = jasmine.createSpy()
var vm = new Vue({
el: el,
template: '<div v-component="{{view}}" keep-alive></div>',
template: '<component type="{{view}}" keep-alive></component>',
data: {
view: 'a'
},
components: {
a: {
created: spyA,
template: 'AAA'
template: '<div>AAA</div>',
replace: true
},
b: {
created: spyB,
template: 'BBB'
template: '<div>BBB</div>',
replace: true
}
}
})
@ -169,7 +173,7 @@ if (_.inBrowser) {
ok: false,
message: 'hello'
},
template: '<div v-component="test" v-show="ok">{{message}}</div>',
template: '<test v-show="ok">{{message}}</test>',
components: {
test: {
template: '<div><content></content> {{message}}</div>',
@ -200,7 +204,7 @@ if (_.inBrowser) {
ok: false,
message: 'hello'
},
template: '<div v-component="test" v-if="ok">{{message}}</div>',
template: '<test v-if="ok">{{message}}</test>',
components: {
test: {
template: '<content></content> {{message}}',
@ -230,10 +234,11 @@ if (_.inBrowser) {
data: {
list: [{a:1}, {a:2}]
},
template: '<ul v-component="test" collection="{{list}}"></ul>',
template: '<test collection="{{list}}"></test>',
components: {
test: {
template: '<li v-repeat="collection">{{a}}</li>',
template: '<ul><li v-repeat="collection">{{a}}</li></ul>',
replace: true,
props: ['collection']
}
}
@ -247,7 +252,7 @@ if (_.inBrowser) {
data: {
view: 'a'
},
template: '<div v-component="{{view}}" wait-for="ok"></div>',
template: '<component type="{{view}}" wait-for="ok"></component>',
components: {
a: {
template: 'AAA'
@ -277,7 +282,7 @@ if (_.inBrowser) {
data: {
view: 'a'
},
template: '<div v-component="{{view}}" v-transition="test" transition-mode="in-out"></div>',
template: '<component type="{{view}}" v-transition="test" transition-mode="in-out"></component>',
components: {
a: { template: 'AAA' },
b: { template: 'BBB' }
@ -317,7 +322,7 @@ if (_.inBrowser) {
data: {
view: 'a'
},
template: '<div v-component="{{view}}" v-transition="test" transition-mode="out-in"></div>',
template: '<component type="{{view}}" v-transition="test" transition-mode="out-in"></component>',
components: {
a: { template: 'AAA' },
b: { template: 'BBB' }
@ -351,7 +356,7 @@ if (_.inBrowser) {
it('teardown', function (done) {
var vm = new Vue({
el: el,
template: '<div v-component="{{view}}" keep-alive></div>',
template: '<component type="{{view}}" keep-alive></component>',
data: {
view: 'test'
},
@ -375,7 +380,7 @@ if (_.inBrowser) {
})
it('already mounted warn', function () {
el.setAttribute('v-component', 'test')
el.setAttribute('v-_component', 'test')
var vm = new Vue({
el: el
})

View File

@ -14,7 +14,7 @@ if (_.inBrowser) {
var spy = jasmine.createSpy('v-events')
new Vue({
el: el,
template: '<div v-component="test" v-events="test:test"></div>',
template: '<test v-events="test:test"></test>',
methods: {
test: spy
},
@ -43,7 +43,7 @@ if (_.inBrowser) {
var spy = jasmine.createSpy('v-events')
new Vue({
el: el,
template: '<div v-component="test"></div>',
template: '<test></test>',
methods: {
test: spy
},
@ -67,7 +67,7 @@ if (_.inBrowser) {
var vm = new Vue({
el: el,
data: { test: 123 },
template: '<div v-component="test" v-events="test:test"></div>',
template: '<test v-events="test:test"></test>',
components: {
test: {}
}
@ -79,7 +79,7 @@ if (_.inBrowser) {
var vm = new Vue({
el: el,
data: {a:1},
template: '<div v-component="test" v-events="test:a++"></div>',
template: '<test v-events="test:a++"></test>',
components: {
test: {
compiled: function () {
@ -104,7 +104,7 @@ if (_.inBrowser) {
a++
}
},
template: '<div v-component="test" v-events="test:handle"></div>',
template: '<test v-events="test:handle"></test>',
components: {
test: {
compiled: function () {

View File

@ -18,7 +18,7 @@ if (_.inBrowser) {
var vm = new Vue({
el: el,
data: { test: false, a: 'A' },
template: '<div v-if="test"><div v-component="test"></div></div>',
template: '<div v-if="test"><test></test></div>',
components: {
test: {
inherit: true,
@ -31,7 +31,7 @@ if (_.inBrowser) {
expect(vm._children.length).toBe(0)
vm.test = true
_.nextTick(function () {
expect(el.innerHTML).toBe(wrap('<div><div>A</div><!--v-component--></div>'))
expect(el.innerHTML).toBe(wrap('<div><test>A</test><!--v-component--></div>'))
expect(vm._children.length).toBe(1)
vm.test = false
_.nextTick(function () {
@ -39,7 +39,7 @@ if (_.inBrowser) {
expect(vm._children.length).toBe(0)
vm.test = true
_.nextTick(function () {
expect(el.innerHTML).toBe(wrap('<div><div>A</div><!--v-component--></div>'))
expect(el.innerHTML).toBe(wrap('<div><test>A</test><!--v-component--></div>'))
expect(vm._children.length).toBe(1)
var child = vm._children[0]
vm.$destroy()
@ -76,7 +76,7 @@ if (_.inBrowser) {
var vm = new Vue({
el: el,
data: { ok: false },
template: '<div v-component="test" v-if="ok"></div>',
template: '<test v-if="ok"></test>',
components: {
test: {
data: function () {
@ -94,7 +94,7 @@ if (_.inBrowser) {
expect(vm._children.length).toBe(0)
vm.ok = true
_.nextTick(function () {
expect(el.innerHTML).toBe(wrap('<div>123</div><!--v-component-->'))
expect(el.innerHTML).toBe(wrap('<test>123</test><!--v-component-->'))
expect(vm._children.length).toBe(1)
expect(attachSpy).toHaveBeenCalled()
expect(readySpy).toHaveBeenCalled()
@ -116,7 +116,7 @@ if (_.inBrowser) {
ok: false,
view: 'a'
},
template: '<div v-component="{{view}}" v-if="ok"></div>',
template: '<component type="{{view}}" v-if="ok"></component>',
components: {
a: {
template: 'AAA'
@ -131,12 +131,12 @@ if (_.inBrowser) {
// toggle if with lazy instantiation
vm.ok = true
_.nextTick(function () {
expect(el.innerHTML).toBe(wrap('<div>AAA</div><!--v-component-->'))
expect(el.innerHTML).toBe(wrap('<component>AAA</component><!--v-component-->'))
expect(vm._children.length).toBe(1)
// switch view when if=true
vm.view = 'b'
_.nextTick(function () {
expect(el.innerHTML).toBe(wrap('<div>BBB</div><!--v-component-->'))
expect(el.innerHTML).toBe(wrap('<component>BBB</component><!--v-component-->'))
expect(vm._children.length).toBe(1)
// toggle if when already instantiated
vm.ok = false
@ -147,7 +147,7 @@ if (_.inBrowser) {
vm.view = 'a'
vm.ok = true
_.nextTick(function () {
expect(el.innerHTML).toBe(wrap('<div>AAA</div><!--v-component-->'))
expect(el.innerHTML).toBe(wrap('<component>AAA</component><!--v-component-->'))
expect(vm._children.length).toBe(1)
done()
})
@ -187,7 +187,7 @@ if (_.inBrowser) {
a: 1,
show: true
},
template: '<div v-component="test" show="{{show}}">{{a}}</div>',
template: '<test show="{{show}}">{{a}}</test>',
components: {
test: {
props: ['show'],
@ -219,7 +219,7 @@ if (_.inBrowser) {
var vm = new Vue({
el: el,
data: { show: true },
template: '<div v-component="outer"><div v-component="transcluded"></div></div>',
template: '<outer><transcluded></transcluded></outer>',
components: {
outer: {
template: '<div v-if="$parent.show"><content></content></div>'
@ -251,11 +251,11 @@ if (_.inBrowser) {
list: [{a:0}]
},
template:
'<div v-component="outer">' +
'<outer>' +
'<div>' + // an extra layer to test components deep inside the tree
'<div v-repeat="list" v-component="transcluded"></div>' +
'<transcluded v-repeat="list"></transcluded>' +
'</div>' +
'</div>',
'</outer>',
components: {
outer: {
template:
@ -264,7 +264,7 @@ if (_.inBrowser) {
'</div>' +
// this is to test that compnents that are not in the if block
// should not fire attach/detach when v-if toggles
'<div v-component="transcluded"></div>'
'<transcluded></transcluded>'
},
transcluded: {
template: '{{a}}',
@ -300,16 +300,16 @@ if (_.inBrowser) {
var showBlock = vm.show
? '<div><div>' +
vm.list.map(function (o) {
return '<div>' + o.a + '</div>'
return '<transcluded>' + o.a + '</transcluded>'
}).join('') + '<!--v-repeat-->' +
'</div></div>'
: ''
var markup = '<div>' +
var markup = '<outer>' +
'<!--v-if-start-->' +
showBlock +
'<!--v-if-end-->' +
'<div></div><!--v-component-->' +
'</div><!--v-component-->'
'<transcluded></transcluded><!--v-component-->' +
'</outer><!--v-component-->'
expect(el.innerHTML).toBe(markup)
}
})

View File

@ -19,7 +19,7 @@ if (_.inBrowser) {
a: 'A'
}
},
template: '<div v-component="test" testt="{{test}}" bb="{{b}}" v-ref="child"></div>',
template: '<test testt="{{test}}" bb="{{b}}" v-ref="child"></test>',
components: {
test: {
props: ['testt', 'bb'],
@ -64,7 +64,7 @@ if (_.inBrowser) {
data: {
b: 'B'
},
template: '<div v-component="test" bb="{{b}}"></div>',
template: '<test bb="{{b}}"></test>',
components: {
test: {
props: ['bb'],
@ -88,7 +88,7 @@ if (_.inBrowser) {
it('block instance with replace:true', function () {
var vm = new Vue({
el: el,
template: '<div v-component="test" b="{{a}}" c="{{d}}"></div>',
template: '<test b="{{a}}" c="{{d}}"></test>',
data: {
a: 'AAA',
d: 'DDD'

View File

@ -23,7 +23,7 @@ if (_.inBrowser) {
var vm = new Vue({
el: el,
components: components,
template: '<div v-component="test" v-ref="test"></div>'
template: '<test v-ref="test"></test>'
})
expect(vm.$.test).toBeTruthy()
expect(vm.$.test.$options.id).toBe('test')
@ -34,7 +34,7 @@ if (_.inBrowser) {
el: el,
components: components,
data: { test: 'test' },
template: '<div v-component="{{test}}" v-ref="test"></div>'
template: '<component type="{{test}}" v-ref="test"></component>'
})
expect(vm.$.test.$options.id).toBe('test')
vm.test = 'test2'
@ -52,7 +52,7 @@ if (_.inBrowser) {
var vm = new Vue({
el: el,
data: { view: 'test1' },
template: '<div v-component="{{view}}"></div>',
template: '<component type="{{view}}"></component>',
components: {
test1: {
id: 'test1',
@ -97,7 +97,7 @@ if (_.inBrowser) {
it('nested v-repeat', function () {
var vm = new Vue({
el: el,
template: '<div v-component="c1" v-ref="c1"></div>',
template: '<c1 v-ref="c1"></c1>',
components: {
c1: {
template: '<div v-repeat="2" v-ref="c2"></div>'

View File

@ -138,13 +138,13 @@ if (_.inBrowser) {
expect(el.innerHTML).toBe('<div>aaa</div><!--v-repeat-->')
})
it('v-component', function (done) {
it('component', function (done) {
var vm = new Vue({
el: el,
data: {
items: [{a:1}, {a:2}]
},
template: '<p v-repeat="items" v-component="test"></p>',
template: '<test v-repeat="items"></test>',
components: {
test: {
template: '<div>{{$index}} {{a}}</div>',
@ -155,16 +155,16 @@ if (_.inBrowser) {
assertMutations(vm, el, done)
})
it('v-component with inline-template', function (done) {
it('component with inline-template', function (done) {
var vm = new Vue({
el: el,
data: {
items: [{a:1}, {a:2}]
},
template:
'<div v-repeat="items" v-component="test" inline-template>' +
'<test v-repeat="items" inline-template>' +
'{{$index}} {{a}}' +
'</div>',
'</test>',
components: {
test: {}
}
@ -172,30 +172,13 @@ if (_.inBrowser) {
assertMutations(vm, el, done)
})
it('v-component with inline-template on <template>', function (done) {
var vm = new Vue({
el: el,
data: {
items: [{a:1}, {a:2}]
},
template:
'<template v-repeat="items" v-component="test" inline-template>' +
'<div>{{$index}} {{a}}</div>' +
'</template>',
components: {
test: {}
}
})
assertMutations(vm, el, done, true)
})
it('v-component with primitive values', function (done) {
it('component with primitive values', function (done) {
var vm = new Vue({
el: el,
data: {
items: [2, 1, 2]
},
template: '<p v-repeat="items" v-component="test"></p>',
template: '<test v-repeat="items"></test>',
components: {
test: {
template: '<div>{{$index}} {{$value}}</div>',
@ -206,7 +189,7 @@ if (_.inBrowser) {
assertPrimitiveMutations(vm, el, done)
})
it('v-component with object of objects', function (done) {
it('component with object of objects', function (done) {
var vm = new Vue({
el: el,
data: {
@ -215,7 +198,7 @@ if (_.inBrowser) {
b: {a:2}
}
},
template: '<p v-repeat="items" v-component="test"></p>',
template: '<test v-repeat="items"></test>',
components: {
test: {
template: '<div>{{$index}} {{$key}} {{a}}</div>',
@ -226,44 +209,6 @@ if (_.inBrowser) {
assertObjectMutations(vm, el, done)
})
it('custom element component', function () {
var vm = new Vue({
el: el,
data: {
items: [{a:1}, {a:2}, {a:3}]
},
template: '<test-component v-repeat="items"></test-component>',
components: {
'test-component': {
template: '{{$index}} {{a}}'
}
}
})
expect(el.innerHTML).toBe(
'<test-component>0 1</test-component>' +
'<test-component>1 2</test-component>' +
'<test-component>2 3</test-component>' +
'<!--v-repeat-->'
)
})
it('custom element component with replace:true', function () {
var vm = new Vue({
el: el,
data: {
items: [{a:1}, {a:2}, {a:3}]
},
template: '<test-component v-repeat="items"></test-component>',
components: {
'test-component': {
template: '<p>{{$index}} {{a}}</p>',
replace: true
}
}
})
expect(el.innerHTML).toBe('<p>0 1</p><p>1 2</p><p>2 3</p><!--v-repeat-->')
})
it('nested repeats', function () {
var vm = new Vue({
el: el,
@ -309,7 +254,7 @@ if (_.inBrowser) {
it('dynamic component type based on instance data', function () {
var vm = new Vue({
el: el,
template: '<div v-repeat="list" v-component="view-{{type}}"></div>',
template: '<component v-repeat="list" type="view-{{type}}"></component>',
data: {
list: [
{ type: 'a' },
@ -329,11 +274,11 @@ if (_.inBrowser) {
}
}
})
expect(el.innerHTML).toBe('<div>AAA</div><div>BBB</div><div>CCC</div><!--v-repeat-->')
expect(el.innerHTML).toBe('<component>AAA</component><component>BBB</component><component>CCC</component><!--v-repeat-->')
// #458 meta properties
vm = new Vue({
el: el,
template: '<div v-repeat="list" v-component="view-{{$value}}"></div>',
template: '<component v-repeat="list" type="view-{{$value}}"></component>',
data: {
list: ['a', 'b', 'c']
},
@ -349,7 +294,7 @@ if (_.inBrowser) {
}
}
})
expect(el.innerHTML).toBe('<div>AAA</div><div>BBB</div><div>CCC</div><!--v-repeat-->')
expect(el.innerHTML).toBe('<component>AAA</component><component>BBB</component><component>CCC</component><!--v-repeat-->')
})
it('block repeat', function (done) {
@ -379,43 +324,10 @@ if (_.inBrowser) {
}
})
// added for #799
it('block repeat with diff', function (done) {
var vm = new Vue({
el: el,
template: '<template v-repeat="list" v-component="test"></template>',
data: {
list: [
{ a: 1 },
{ a: 2 },
{ a: 3 }
]
},
components: {
test: {
template: '<p>{{a}}</p><p>{{a + 1}}</p>'
}
}
})
assertMarkup()
vm.list.reverse()
_.nextTick(function () {
assertMarkup()
done()
})
function assertMarkup () {
var markup = vm.list.map(function (item) {
return '<!--v-start--><p>' + item.a + '</p><p>' + (item.a + 1) + '</p><!--v-end-->'
}).join('')
expect(el.innerHTML).toBe(markup + '<!--v-repeat-->')
}
})
it('component + parent directive + transclusion', function (done) {
var vm = new Vue({
el: el,
template: '<div v-repeat="list" v-component="test" v-class="cls">{{msg}}</div>',
template: '<test v-repeat="list" v-class="cls">{{msg}}</test>',
data: {
cls: 'parent',
msg: 'hi',
@ -538,8 +450,8 @@ if (_.inBrowser) {
it('track by id', function (done) {
assertTrackBy('<div v-repeat="list" v-component="test" track-by="id"></div>', '{{msg}}', function () {
assertTrackBy('<div v-repeat="item:list" v-component="test" track-by="id"></div>', '{{item.msg}}', done)
assertTrackBy('<test v-repeat="list" track-by="id"></test>', '{{msg}}', function () {
assertTrackBy('<test v-repeat="item:list" track-by="id"></test>', '{{item.msg}}', done)
})
function assertTrackBy (template, componentTemplate, next) {
@ -579,7 +491,7 @@ if (_.inBrowser) {
function assertMarkup () {
var markup = vm.list.map(function (item) {
return '<div>' + item.msg + '</div>'
return '<test>' + item.msg + '</test>'
}).join('')
expect(el.innerHTML).toBe(markup + '<!--v-repeat-->')
}
@ -848,8 +760,9 @@ function assertMutations (vm, el, done, isBlock) {
.run(done)
function assertMarkup () {
var tag = el.children[0].tagName.toLowerCase()
var markup = vm.items.map(function (item, i) {
var el = '<div>' + i + ' ' + item.a + '</div>'
var el = '<' + tag + '>' + i + ' ' + item.a + '</' + tag + '>'
if (isBlock) el = '<!--v-start-->' + el + '<!--v-end-->'
return el
}).join('')

View File

@ -26,13 +26,13 @@ describe('Misc', function () {
var spy1 = jasmine.createSpy('attached')
var spy2 = jasmine.createSpy('detached')
var el = document.createElement('div')
el.innerHTML = '<div v-component="outter" v-ref="outter"><div v-component="inner"></div></div>'
el.innerHTML = '<outer v-ref="outter"><inner></inner></outer>'
document.body.appendChild(el)
var vm = new Vue({
el: el,
components: {
outter: {
outer: {
template: '<content></content>'
},
inner: {
@ -51,7 +51,7 @@ describe('Misc', function () {
var el = document.createElement('div')
var vm = new Vue({
el: el,
template: '<div v-component="test"></div>',
template: '<test></test>',
components: {
test: {
data: function () {