فهرست منبع

do not set up watchers if v-with is bound to literal value (fix #776 & #813)

Evan You 11 سال پیش
والد
کامیت
2d3cf2d589
2فایلهای تغییر یافته به همراه43 افزوده شده و 0 حذف شده
  1. 13 0
      src/directives/with.js
  2. 30 0
      test/unit/specs/directives/with_spec.js

+ 13 - 0
src/directives/with.js

@@ -1,5 +1,7 @@
 var _ = require('../util')
 var Watcher = require('../watcher')
+var expParser = require('../parsers/expression')
+var literalRE = /^(true|false|\s?('[^']*'|"[^"]")\s?)$/
 
 module.exports = {
 
@@ -20,6 +22,17 @@ module.exports = {
       _.warn(
         'v-with must be used on an instance with a parent.'
       )
+    } else if (literalRE.test(parentKey)) {
+      // no need to setup watchers for literal bindings
+      if (!this.arg) {
+        _.warn(
+          'v-with cannot bind literal value as $data: ' +
+          parentKey
+        )
+      } else {
+        var value = expParser.parse(parentKey).get()
+        child.$set(childKey, value)
+      }
     } else {
 
       // simple lock to avoid circular updates.

+ 30 - 0
test/unit/specs/directives/with_spec.js

@@ -152,5 +152,35 @@ if (_.inBrowser) {
       expect(el.innerHTML).toBe('<!--v-start--><p>AAA</p><p>DDD</p><!--v-end--><!--v-component-->')
     })
 
+    it('bind literal values should not trigger setter warning', function (done) {
+      var vm = new Vue({
+        el: el,
+        template: '<div v-component="test" v-with="a:\'test\'"></div>',
+        components: {
+          test: {
+            template: '{{a}}'
+          }
+        }
+      })
+      expect(el.firstChild.innerHTML).toBe('test')
+      vm._children[0].a = 'changed'
+      _.nextTick(function () {
+        expect(el.firstChild.innerHTML).toBe('changed')
+        expect(_.warn).not.toHaveBeenCalled()
+        done()
+      })
+    })
+
+    it('should warn when binding literal value without childKey', function () {
+      var vm = new Vue({
+        el: el,
+        template: '<div v-component="test" v-with="\'test\'"></div>',
+        components: {
+          test: {}
+        }
+      })
+      expect(_.warn).toHaveBeenCalled()
+    })
+
   })
 }