Răsfoiți Sursa

implement inline-template param for v-component

Evan You 11 ani în urmă
părinte
comite
bd47f1c71e

+ 6 - 0
src/directives/component.js

@@ -31,6 +31,11 @@ module.exports = {
       if (this.keepAlive) {
         this.cache = {}
       }
+      // check inline-template
+      if (this._checkParam('inline-template') !== null) {
+        // extract inline template as a DocumentFragment
+        this.template = _.extractContent(this.el, true)
+      }
       // if static, build right now.
       if (!this._isDynamicLiteral) {
         this.resolveCtor(this.expression)
@@ -81,6 +86,7 @@ module.exports = {
     if (this.Ctor) {
       var child = vm.$addChild({
         el: el,
+        template: this.template,
         _asComponent: true
       }, this.Ctor)
       if (this.keepAlive) {

+ 8 - 1
src/directives/repeat.js

@@ -99,6 +99,11 @@ module.exports = {
       this._linkFn = compile(this.template, options)
     } else {
       this.asComponent = true
+      // check inline-template
+      if (this._checkParam('inline-template') !== null) {
+        // extract inline template as a DocumentFragment
+        this.inlineTempalte = _.extractContent(this.el, true)
+      }
       var tokens = textParser.parse(id)
       if (!tokens) { // static component
         var Ctor = this.Ctor = options.components[id]
@@ -114,6 +119,7 @@ module.exports = {
           var merged = mergeOptions(Ctor.options, {}, {
             $parent: this.vm
           })
+          merged.template = this.inlineTempalte || merged.template
           this.template = transclude(this.template, merged)
           this._linkFn = compile(this.template, merged, false, true)
         }
@@ -337,7 +343,8 @@ module.exports = {
       _linkFn: this._linkFn,
       _meta: meta,
       data: data,
-      inherit: this.inherit
+      inherit: this.inherit,
+      template: this.inlineTempalte
     }, Ctor)
     // flag this instance as a repeat instance
     // so that we can skip it in vm._digest

+ 5 - 2
src/util/dom.js

@@ -180,14 +180,17 @@ exports.removeClass = function (el, cls) {
  * container div
  *
  * @param {Element} el
+ * @param {Boolean} asFragment
  * @return {Element}
  */
 
-exports.extractContent = function (el) {
+exports.extractContent = function (el, asFragment) {
   var child
   var rawContent
   if (el.hasChildNodes()) {
-    rawContent = document.createElement('div')
+    rawContent = asFragment
+      ? document.createDocumentFragment()
+      : document.createElement('div')
     /* jshint boss:true */
     while (child = el.firstChild) {
       rawContent.appendChild(child)

+ 19 - 0
test/unit/specs/directives/component_spec.js

@@ -50,6 +50,25 @@ if (_.inBrowser) {
       expect(el.innerHTML).toBe('<p>123</p><!--v-component-->')
     })
 
+    it('inline-template', function () {
+      var vm = new Vue({
+        el: el,
+        template: '<div v-component="test" inline-template>{{a}}</div>',
+        data: {
+          a: 'parent'
+        },
+        components: {
+          test: {
+            data: function () {
+              return { a: 'child' }
+            },
+            template: 'child option template'
+          }
+        }
+      })
+      expect(el.innerHTML).toBe('<div>child</div><!--v-component-->')
+    })
+
     it('block replace', function () {
       var vm = new Vue({
         el: el,

+ 17 - 0
test/unit/specs/directives/repeat_spec.js

@@ -157,6 +157,23 @@ if (_.inBrowser) {
       assertMutations(vm, el, done)
     })
 
+    it('v-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>' +
+            '{{$index}} {{a}}' +
+          '</div>',
+        components: {
+          test: {}
+        }
+      })
+      assertMutations(vm, el, done)
+    })
+
     it('v-component with primitive values', function (done) {
       var vm = new Vue({
         el: el,