Skip to content

Commit d3027a2

Browse files
committed
do not cast empty string when initializing props (fix vuejs#1107)
1 parent 6d4ddd6 commit d3027a2

File tree

3 files changed

+22
-11
lines changed

3 files changed

+22
-11
lines changed

src/compiler/compile-props.js

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -138,9 +138,14 @@ function makePropsLinkFn (props) {
138138
}
139139
} else {
140140
// literal, cast it and just set once
141-
value = options.type === Boolean && prop.raw === ''
141+
var raw = prop.raw
142+
value = options.type === Boolean && raw === ''
142143
? true
143-
: _.toBoolean(_.toNumber(prop.raw))
144+
// do not cast emptry string.
145+
// _.toNumber casts empty string to 0.
146+
: raw.trim()
147+
? _.toBoolean(_.toNumber(raw))
148+
: raw
144149
_.initProp(vm, prop, value)
145150
}
146151
}

src/util/lang.js

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -25,20 +25,22 @@ exports.toString = function (value) {
2525
}
2626

2727
/**
28-
* Check and convert possible numeric numbers before
29-
* setting back to data
28+
* Check and convert possible numeric strings to numbers
29+
* before setting back to data
3030
*
3131
* @param {*} value
3232
* @return {*|Number}
3333
*/
3434

3535
exports.toNumber = function (value) {
36-
return (
37-
isNaN(value) ||
38-
value === null ||
39-
typeof value === 'boolean'
40-
) ? value
41-
: Number(value)
36+
if (typeof value !== 'string') {
37+
return value
38+
} else {
39+
var parsed = Number(value)
40+
return isNaN(parsed)
41+
? value
42+
: parsed
43+
}
4244
}
4345

4446
/**

test/unit/specs/compiler/compile_spec.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,7 @@ if (_.inBrowser) {
148148
var bindingModes = Vue.config._propBindingModes
149149
var props = [
150150
'a',
151+
'empty',
151152
'data-some-attr',
152153
'some-other-attr',
153154
'multiple-attrs',
@@ -187,6 +188,7 @@ if (_.inBrowser) {
187188
})
188189
var def = Vue.options.directives._prop
189190
el.setAttribute('a', '1')
191+
el.setAttribute('empty', '')
190192
el.setAttribute('data-some-attr', '{{a}}')
191193
el.setAttribute('some-other-attr', '2')
192194
el.setAttribute('multiple-attrs', 'a {{b}} c')
@@ -237,9 +239,11 @@ if (_.inBrowser) {
237239
expect(hasWarned(_, 'expects a two-way binding type')).toBe(true)
238240
// literal and one time should've been set on the _data
239241
// and numbers should be casted
240-
expect(Object.keys(vm._data).length).toBe(10)
242+
expect(Object.keys(vm._data).length).toBe(11)
241243
expect(vm.a).toBe(1)
242244
expect(vm._data.a).toBe(1)
245+
expect(vm.empty).toBe('')
246+
expect(vm._data.empty).toBe('')
243247
expect(vm.someOtherAttr).toBe(2)
244248
expect(vm._data.someOtherAttr).toBe(2)
245249
expect(vm.onetime).toBe('from parent: a')

0 commit comments

Comments
 (0)