Skip to content

Commit 31565cc

Browse files
committed
improve Boolean props handling per discussions in #981
1 parent 3981561 commit 31565cc

File tree

2 files changed

+24
-11
lines changed

2 files changed

+24
-11
lines changed

src/compiler/compile.js

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -509,16 +509,18 @@ function compileProps (el, propOptions) {
509509
function makePropsLinkFn (props) {
510510
return function propsLinkFn (vm, el) {
511511
var i = props.length
512-
var prop, path, value
512+
var prop, path, options, value
513513
while (i--) {
514514
prop = props[i]
515515
path = prop.path
516+
options = prop.options
516517
if (prop.raw === null) {
517-
// initialize undefined prop
518-
vm._data[path] = (
519-
prop.options &&
520-
prop.options.default
521-
) || undefined
518+
// initialize absent prop
519+
vm._data[path] = options.type === Boolean
520+
? false
521+
: options.hasOwnProperty('default')
522+
? options.default
523+
: undefined
522524
} else if (prop.dynamic) {
523525
// dynamic prop
524526
if (vm._context) {
@@ -541,7 +543,9 @@ function makePropsLinkFn (props) {
541543
}
542544
} else {
543545
// literal, cast it and just set once
544-
value = _.toBoolean(_.toNumber(prop.raw))
546+
value = options.type === Boolean && prop.raw === ''
547+
? true
548+
: _.toBoolean(_.toNumber(prop.raw))
545549
if (_.assertProp(prop, value)) {
546550
vm[path] = vm._data[path] = value
547551
}

test/unit/specs/compiler/compile_spec.js

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -160,11 +160,17 @@ if (_.inBrowser) {
160160
{
161161
name: 'default-value',
162162
default: 123
163+
},
164+
{
165+
name: 'boolean',
166+
type: Boolean
167+
},
168+
{
169+
name: 'boolean-absent',
170+
type: Boolean
163171
}
164172
].map(function (p) {
165-
return typeof p === 'string'
166-
? { name: p }
167-
: p
173+
return typeof p === 'string' ? { name: p } : p
168174
})
169175
var def = Vue.options.directives._prop
170176
el.setAttribute('a', '1')
@@ -175,6 +181,7 @@ if (_.inBrowser) {
175181
el.setAttribute('twoway', '{{@a}}')
176182
el.setAttribute('with-filter', '{{a | filter}}')
177183
el.setAttribute('boolean-literal', '{{true}}')
184+
el.setAttribute('boolean', '')
178185
compiler.compileAndLinkProps(vm, el, props)
179186
// should skip literals and one-time bindings
180187
expect(vm._bindDir.calls.count()).toBe(4)
@@ -212,7 +219,7 @@ if (_.inBrowser) {
212219
expect(args[3]).toBe(def)
213220
// literal and one time should've been set on the _data
214221
// and numbers should be casted
215-
expect(Object.keys(vm._data).length).toBe(6)
222+
expect(Object.keys(vm._data).length).toBe(8)
216223
expect(vm.a).toBe(1)
217224
expect(vm._data.a).toBe(1)
218225
expect(vm.someOtherAttr).toBe(2)
@@ -223,6 +230,8 @@ if (_.inBrowser) {
223230
expect(vm._data.booleanLiteral).toBe('from parent: true')
224231
expect(vm._data.camelCase).toBeUndefined()
225232
expect(vm._data.defaultValue).toBe(123)
233+
expect(vm._data.boolean).toBe(true)
234+
expect(vm._data.booleanAbsent).toBe(false)
226235
// camelCase should've warn
227236
expect(hasWarned(_, 'using camelCase')).toBe(true)
228237
})

0 commit comments

Comments
 (0)