Przeglądaj źródła

bring partials back

Evan You 11 lat temu
rodzic
commit
6b7f9d9a1e

+ 8 - 8
src/directives/if.js

@@ -28,7 +28,7 @@ module.exports = {
       this.invalid = true
       _.warn(
         'v-if="' + this.expression + '" cannot be ' +
-        'used on an already mounted instance.'
+        'used on an instance root element.'
       )
     }
   },
@@ -39,19 +39,19 @@ module.exports = {
       // avoid duplicate compiles, since update() can be
       // called with different truthy values
       if (!this.unlink) {
-        this.compile()
+        this.link(
+          templateParser.clone(this.template),
+          this.linker
+        )
       }
     } else {
       this.teardown()
     }
   },
 
-  compile: function () {
+  link: function (frag, linker) {
     var vm = this.vm
-    var frag = templateParser.clone(this.template)
-    // the linker is not guaranteed to be present because
-    // this function might get called by v-partial 
-    this.unlink = this.linker(vm, frag)
+    this.unlink = linker(vm, frag)
     transition.blockAppend(frag, this.end, vm)
     // call attached for all the child components created
     // during the compilation
@@ -124,4 +124,4 @@ function callDetach (child) {
   if (child._isAttached) {
     child._callHook('detached')
   }
-}
+}

+ 0 - 0
src/compiler/content.js → src/element-directives/content.js


+ 2 - 0
src/element-directives/index.js

@@ -0,0 +1,2 @@
+exports.content = require('./content')
+exports.partial = require('./partial')

+ 69 - 0
src/element-directives/partial.js

@@ -0,0 +1,69 @@
+var _ = require('../util')
+var templateParser = require('../parsers/template')
+var textParser = require('../parsers/text')
+var compiler = require('../compiler')
+var Cache = require('../cache')
+var cache = new Cache(1000)
+
+// v-partial reuses logic from v-if
+var vIf = require('../directives/if')
+
+module.exports = {
+
+  link: vIf.link,
+  teardown: vIf.teardown,
+  getContainedComponents: vIf.getContainedComponents,
+
+  bind: function () {
+    var el = this.el
+    this.start = _.createAnchor('v-partial-start')
+    this.end = _.createAnchor('v-partial-end')
+    _.replace(el, this.end)
+    _.before(this.start, this.end)
+    var id = el.getAttribute('name')
+    var tokens = textParser.parse(id)
+    if (tokens) {
+      // dynamic partial
+      this.setupDynamic(tokens)
+    } else {
+      // static partial
+      this.insert(id)
+    }
+  },
+
+  setupDynamic: function (tokens) {
+    var self = this
+    var exp = textParser.tokensToExp(tokens)
+    this.unwatch = this.vm.$watch(exp, function (value) {
+      self.teardown()
+      self.insert(value)
+    }, {
+      immediate: true,
+      user: false
+    })
+  },
+
+  insert: function (id) {
+    var partial = this.vm.$options.partials[id]
+    _.assertAsset(partial, 'partial', id)
+    if (partial) {
+      var frag = templateParser.parse(partial, true)
+      var linker = this.compile(frag, partial)
+      // this is provided by v-if
+      this.link(frag, linker)
+    }
+  },
+
+  compile: function (frag, partial) {
+    var hit = cache.get(partial)
+    if (hit) return hit
+    var linker = compiler.compile(frag, this.vm.$options, true)
+    cache.put(partial, linker)
+    return linker
+  },
+
+  unbind: function () {
+    if (this.unlink) this.unlink()
+    if (this.unwatch) this.unwatch()
+  }
+}

+ 1 - 0
src/util/options.js

@@ -149,6 +149,7 @@ strats.directives =
 strats.filters =
 strats.transitions =
 strats.components =
+strats.partials =
 strats.elementDirectives = function (parentVal, childVal) {
   var res = Object.create(parentVal)
   return childVal

+ 3 - 4
src/vue.js

@@ -36,12 +36,11 @@ extend(Vue, require('./api/global'))
 
 Vue.options = {
   directives: require('./directives'),
+  elementDirectives: require('./element-directives'),
   filters: require('./filters'),
   transitions: {},
   components: {},
-  elementDirectives: {
-    content: require('./compiler/content')
-  }
+  partials: {}
 }
 
 /**
@@ -86,4 +85,4 @@ extend(p, require('./api/events'))
 extend(p, require('./api/child'))
 extend(p, require('./api/lifecycle'))
 
-module.exports = _.Vue = Vue
+module.exports = _.Vue = Vue

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

@@ -173,7 +173,7 @@ if (_.inBrowser) {
       var vm = new Vue({
         el: el
       })
-      expect(hasWarned(_, 'already mounted instance')).toBe(true)
+      expect(hasWarned(_, 'cannot be used on an instance root element')).toBe(true)
     })
 
     it('call attach/detach for transcluded components', function (done) {

+ 0 - 0
test/unit/specs/compiler/content_spec.js → test/unit/specs/element-directives/content_spec.js


+ 0 - 0
test/unit/specs/element-directives/partial_spec.js