2
0
Эх сурвалжийг харах

use bind- syntax for props

Evan You 10 жил өмнө
parent
commit
f40e2d7937

+ 38 - 27
src/compiler/compile-props.js

@@ -49,16 +49,12 @@ module.exports = function compileProps (el, propOptions) {
     attr = _.hyphenate(name)
     value = el.getAttribute(attr)
 
-    if (value !== null && process.env.NODE_ENV !== 'production') {
-      _.deprecation.PROPS(attr, value)
-    }
-
     if (value === null) {
       value = el.getAttribute('data-' + attr)
       if (value !== null) {
         attr = 'data-' + attr
         if (process.env.NODE_ENV !== 'production') {
-          _.deprecation.PROPS(attr, value)
+          _.deprecation.DATA_PROPS(attr, value)
         }
       }
     }
@@ -77,6 +73,11 @@ module.exports = function compileProps (el, propOptions) {
       el.removeAttribute(attr)
       var tokens = textParser.parse(value)
       if (tokens) {
+
+        if (process.env.NODE_ENV !== 'production') {
+          _.deprecation.PROPS(attr, value)
+        }
+
         prop.dynamic = true
         prop.parentPath = textParser.tokensToExp(tokens)
         // check prop binding type.
@@ -100,30 +101,35 @@ module.exports = function compileProps (el, propOptions) {
         }
       }
     } else {
-      // new prop- syntax
-      attr = 'prop-' + attr
+      // new syntax
+      attr = 'bind-' + attr
       value = prop.raw = el.getAttribute(attr)
       if (value !== null) {
+        // mark it so we know this is a bind
+        prop.bindSyntax = true
         el.removeAttribute(attr)
+        value = value.trim()
         // check binding type
         if (literalValueRE.test(value)) {
           prop.mode = propBindingModes.ONE_TIME
-        } else if (value.charAt(0) === '*') {
-          prop.mode = propBindingModes.ONE_TIME
-          value = value.slice(1)
-        } else if (value.charAt(0) === '@') {
-          value = value.slice(1)
-          if (settablePathRE.test(value)) {
-            prop.mode = propBindingModes.TWO_WAY
-          } else {
-            process.env.NODE_ENV !== 'production' && _.warn(
-              'Cannot bind two-way prop with non-settable ' +
-              'parent path: ' + value
-            )
+        } else {
+          prop.dynamic = true
+          if (value.charAt(0) === '*') {
+            prop.mode = propBindingModes.ONE_TIME
+            value = value.slice(1).trim()
+          } else if (value.charAt(0) === '@') {
+            value = value.slice(1).trim()
+            if (settablePathRE.test(value)) {
+              prop.mode = propBindingModes.TWO_WAY
+            } else {
+              process.env.NODE_ENV !== 'production' && _.warn(
+                'Cannot bind two-way prop with non-settable ' +
+                'parent path: ' + value
+              )
+            }
           }
         }
       }
-      prop.dynamic = true
       prop.parentPath = value
     }
 
@@ -193,13 +199,18 @@ function makePropsLinkFn (props) {
       } else {
         // literal, cast it and just set once
         var raw = prop.raw
-        value = options.type === Boolean && raw === ''
-          ? true
-          // do not cast emptry string.
-          // _.toNumber casts empty string to 0.
-          : raw.trim()
-            ? _.toBoolean(_.toNumber(raw))
-            : raw
+        if (options.type === Boolean && raw === '') {
+          value = true
+        } else if (raw.trim()) {
+          value = _.toBoolean(_.toNumber(raw))
+          if (process.env.NODE_ENV !== 'production' &&
+              !prop.bindSyntax &&
+              value !== raw) {
+            _.deprecation.PROP_CASTING(prop.name, prop.raw)
+          }
+        } else {
+          value = raw
+        }
         _.initProp(vm, prop, value)
       }
     }

+ 18 - 3
src/deprecations.js

@@ -134,9 +134,24 @@ if (process.env.NODE_ENV !== 'production') {
 
     PROPS: function (attr, value) {
       warn(
-        'Prop ' + attr + '="' + value + '" should be prefixed with "prop-" and ' +
-        'bound as expression in 1.0.0. ' +
-        'For more details, see https://github.com/yyx990803/vue/issues/1173'
+        'Prop ' + attr + '="' + value + '": props no longer use mustache tags ' +
+        'to indicate a dynamic binding. Use the "bind-" prefix instead.' +
+        newBindingSyntaxLink
+      )
+    },
+
+    DATA_PROPS: function (attr, value) {
+      warn(
+        'Prop ' + attr + '="' + value + '": props will no longer support the ' +
+        '"data-" prefix in 1.0.0.' + newBindingSyntaxLink
+      )
+    },
+
+    PROP_CASTING: function (attr, value) {
+      warn(
+        'Prop ' + attr + '="' + value + '": literal props will no longer be ' +
+        'auto-casted into booleans/numbers in 1.0.0 - they will all be treated ' +
+        'as literal strings. Use "bind-" syntax for boolean/number literals instead.'
       )
     },
 

+ 12 - 8
test/unit/specs/compiler/compile_spec.js

@@ -305,18 +305,22 @@ if (_.inBrowser) {
         { name: 'testLiteral' },
         { name: 'testTwoWay' },
         { name: 'twoWayWarn' },
-        { name: 'testOneTime' }
+        { name: 'testOneTime' },
+        { name: 'optimizeLiteral' }
       ]
-      el.setAttribute('prop-test-normal', 'a')
-      el.setAttribute('prop-test-literal', '1')
-      el.setAttribute('prop-test-two-way', '@a')
-      el.setAttribute('prop-two-way-warn', '@a + 1')
-      el.setAttribute('prop-test-one-time', '*a')
+      el.setAttribute('bind-test-normal', 'a')
+      el.setAttribute('test-literal', '1')
+      el.setAttribute('bind-optimize-literal', '1')
+      el.setAttribute('bind-test-two-way', '@a')
+      el.setAttribute('bind-two-way-warn', '@a + 1')
+      el.setAttribute('bind-test-one-time', '*a')
       compiler.compileAndLinkProps(vm, el, props)
       expect(vm._bindDir.calls.count()).toBe(3) // skip literal and one time
       // literal
-      expect(vm.testLiteral).toBe('from parent: 1')
-      expect(vm._data.testLiteral).toBe('from parent: 1')
+      expect(vm.testLiteral).toBe(1)
+      expect(vm._data.testLiteral).toBe(1)
+      expect(vm.optimizeLiteral).toBe(1)
+      expect(vm._data.optimizeLiteral).toBe(1)
       // one time
       expect(vm.testOneTime).toBe('from parent: a')
       expect(vm._data.testOneTime).toBe('from parent: a')