Просмотр исходного кода

do not cast empty string when initializing props (fix #1107)

Evan You 10 лет назад
Родитель
Сommit
d3027a2396
3 измененных файлов с 22 добавлено и 11 удалено
  1. 7 2
      src/compiler/compile-props.js
  2. 10 8
      src/util/lang.js
  3. 5 1
      test/unit/specs/compiler/compile_spec.js

+ 7 - 2
src/compiler/compile-props.js

@@ -138,9 +138,14 @@ function makePropsLinkFn (props) {
         }
       } else {
         // literal, cast it and just set once
-        value = options.type === Boolean && prop.raw === ''
+        var raw = prop.raw
+        value = options.type === Boolean && raw === ''
           ? true
-          : _.toBoolean(_.toNumber(prop.raw))
+          // do not cast emptry string.
+          // _.toNumber casts empty string to 0.
+          : raw.trim()
+            ? _.toBoolean(_.toNumber(raw))
+            : raw
         _.initProp(vm, prop, value)
       }
     }

+ 10 - 8
src/util/lang.js

@@ -25,20 +25,22 @@ exports.toString = function (value) {
 }
 
 /**
- * Check and convert possible numeric numbers before
- * setting back to data
+ * Check and convert possible numeric strings to numbers
+ * before setting back to data
  *
  * @param {*} value
  * @return {*|Number}
  */
 
 exports.toNumber = function (value) {
-  return (
-    isNaN(value) ||
-    value === null ||
-    typeof value === 'boolean'
-  ) ? value
-    : Number(value)
+  if (typeof value !== 'string') {
+    return value
+  } else {
+    var parsed = Number(value)
+    return isNaN(parsed)
+      ? value
+      : parsed
+  }
 }
 
 /**

+ 5 - 1
test/unit/specs/compiler/compile_spec.js

@@ -148,6 +148,7 @@ if (_.inBrowser) {
       var bindingModes = Vue.config._propBindingModes
       var props = [
         'a',
+        'empty',
         'data-some-attr',
         'some-other-attr',
         'multiple-attrs',
@@ -187,6 +188,7 @@ if (_.inBrowser) {
       })
       var def = Vue.options.directives._prop
       el.setAttribute('a', '1')
+      el.setAttribute('empty', '')
       el.setAttribute('data-some-attr', '{{a}}')
       el.setAttribute('some-other-attr', '2')
       el.setAttribute('multiple-attrs', 'a {{b}} c')
@@ -237,9 +239,11 @@ if (_.inBrowser) {
       expect(hasWarned(_, 'expects a two-way binding type')).toBe(true)
       // literal and one time should've been set on the _data
       // and numbers should be casted
-      expect(Object.keys(vm._data).length).toBe(10)
+      expect(Object.keys(vm._data).length).toBe(11)
       expect(vm.a).toBe(1)
       expect(vm._data.a).toBe(1)
+      expect(vm.empty).toBe('')
+      expect(vm._data.empty).toBe('')
       expect(vm.someOtherAttr).toBe(2)
       expect(vm._data.someOtherAttr).toBe(2)
       expect(vm.onetime).toBe('from parent: a')