Browse Source

give v-with higest priority among normal directives (fix #282)

Evan You 12 years ago
parent
commit
182fe83e37
2 changed files with 18 additions and 8 deletions
  1. 16 7
      src/compiler.js
  2. 2 1
      test/unit/specs/api.js

+ 16 - 7
src/compiler.js

@@ -523,10 +523,24 @@ CompilerProto.compileElement = function (node, root) {
         node.vue_effect = this.eval(utils.attr(node, 'effect'))
 
         var prefix = config.prefix + '-',
-            attrs = slice.call(node.attributes),
             params = this.options.paramAttributes,
             attr, attrname, isDirective, exp, directives, directive, dirname
 
+        // v-with has special priority among the rest
+        // it needs to pull in the value from the parent before
+        // computed properties are evaluated, because at this stage
+        // the computed properties have not set up their dependencies yet.
+        if (root) {
+            var withExp = utils.attr(node, 'with')
+            if (withExp) {
+                directives = this.parseDirective('with', withExp, node, true)
+                for (j = 0, k = directives.length; j < k; j++) {
+                    this.bindDirective(directives[j], this.parent)
+                }
+            }
+        }
+
+        var attrs = slice.call(node.attributes)
         for (i = 0, l = attrs.length; i < l; i++) {
 
             attr = attrs[i]
@@ -542,12 +556,7 @@ CompilerProto.compileElement = function (node, root) {
                 // loop through clauses (separated by ",")
                 // inside each attribute
                 for (j = 0, k = directives.length; j < k; j++) {
-                    directive = directives[j]
-                    if (dirname === 'with') {
-                        this.bindDirective(directive, this.parent)
-                    } else {
-                        this.bindDirective(directive)
-                    }
+                    this.bindDirective(directives[j])
                 }
             } else if (config.interpolate) {
                 // non directive attribute, check interpolation tags

+ 2 - 1
test/unit/specs/api.js

@@ -680,7 +680,7 @@ describe('API', function () {
                     assert.strictEqual(v.$data.c, null)
                 })
 
-                it('should be able in bind data from parents', function (done) {
+                it('should be able to bind data from parents', function (done) {
                     var v = new Vue({
                         template: '<div v-component="test" v-ref="child"></div>',
                         data: {
@@ -688,6 +688,7 @@ describe('API', function () {
                         },
                         components: {
                             test: {
+                                replace: true,
                                 paramAttributes: ['size'],
                                 template: '<div class="child" size="{{size}}"></div>'
                             }