Browse Source

remove v-component

Evan You 11 years ago
parent
commit
70d5280faa

+ 6 - 4
examples/svg/index.html

@@ -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">

+ 1 - 0
examples/svg/svg.js

@@ -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 () {

+ 15 - 15
examples/tree/index.html

@@ -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 -->

+ 1 - 0
examples/tree/tree.js

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

+ 35 - 18
src/compiler/compile.js

@@ -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.

+ 3 - 3
src/compiler/transclude.js

@@ -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--) {

+ 1 - 2
src/config.js

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

+ 1 - 1
src/directives/index.js

@@ -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')

+ 1 - 1
src/directives/repeat.js

@@ -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

+ 23 - 1
src/util/index.js

@@ -5,4 +5,26 @@ extend(exports, lang)
 extend(exports, require('./env'))
 extend(exports, require('./dom'))
 extend(exports, require('./filter'))
-extend(exports, require('./debug'))
+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
+  }
+}

+ 12 - 12
test/unit/specs/async_component_spec.js

@@ -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'

+ 17 - 19
test/unit/specs/compiler/compile_spec.js

@@ -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',

+ 26 - 21
test/unit/specs/directives/component_spec.js

@@ -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
       })

+ 5 - 5
test/unit/specs/directives/events_spec.js

@@ -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 () {

+ 19 - 19
test/unit/specs/directives/if_spec.js

@@ -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)
       }
     })

+ 3 - 3
test/unit/specs/directives/prop_spec.js

@@ -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'

+ 4 - 4
test/unit/specs/directives/ref_spec.js

@@ -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>'

+ 19 - 106
test/unit/specs/directives/repeat_spec.js

@@ -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('')

+ 3 - 3
test/unit/specs/misc_spec.js

@@ -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 () {