Skip to content

Commit 04116fc

Browse files
committed
props should use default value if passed value is undefined
1 parent b781ab0 commit 04116fc

File tree

3 files changed

+55
-36
lines changed

3 files changed

+55
-36
lines changed

src/compiler/compile-props.js

Lines changed: 2 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,9 @@ import {
99
getBindAttr,
1010
isLiteral,
1111
initProp,
12-
hasOwn,
1312
toBoolean,
1413
toNumber,
15-
stripQuotes,
16-
isObject
14+
stripQuotes
1715
} from '../util/index'
1816

1917
const propBindingModes = config._propBindingModes
@@ -165,7 +163,7 @@ function makePropsLinkFn (props) {
165163
vm._props[path] = prop
166164
if (raw === null) {
167165
// initialize absent prop
168-
initProp(vm, prop, getDefault(vm, options))
166+
initProp(vm, prop, undefined)
169167
} else if (prop.dynamic) {
170168
// dynamic prop
171169
if (prop.mode === propBindingModes.ONE_TIME) {
@@ -203,34 +201,3 @@ function makePropsLinkFn (props) {
203201
}
204202
}
205203
}
206-
207-
/**
208-
* Get the default value of a prop.
209-
*
210-
* @param {Vue} vm
211-
* @param {Object} options
212-
* @return {*}
213-
*/
214-
215-
function getDefault (vm, options) {
216-
// no default, return undefined
217-
if (!hasOwn(options, 'default')) {
218-
// absent boolean value defaults to false
219-
return options.type === Boolean
220-
? false
221-
: undefined
222-
}
223-
var def = options.default
224-
// warn against non-factory defaults for Object & Array
225-
if (isObject(def)) {
226-
process.env.NODE_ENV !== 'production' && warn(
227-
'Object/Array as default prop values will be shared ' +
228-
'across multiple instances. Use a factory function ' +
229-
'to return the default value instead.'
230-
)
231-
}
232-
// call factory function for non-Function types
233-
return typeof def === 'function' && options.type !== Function
234-
? def.call(vm)
235-
: def
236-
}

src/util/component.js

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { warn } from './debug'
22
import { resolveAsset } from './options'
33
import { getAttr, getBindAttr } from './dom'
4-
import { isArray, isPlainObject } from './lang'
4+
import { isArray, isPlainObject, isObject, hasOwn } from './lang'
55

66
export const commonTagRE = /^(div|p|span|img|a|b|i|br|ul|ol|li|h1|h2|h3|h4|h5|h6|code|pre|table|th|td|tr|form|label|input|select|option|nav|article|section|header|footer)$/
77
export const reservedTagRE = /^(slot|partial|component)$/
@@ -100,11 +100,45 @@ function getIsBinding (el) {
100100
export function initProp (vm, prop, value) {
101101
const key = prop.path
102102
value = coerceProp(prop, value)
103+
if (value === undefined) {
104+
value = getPropDefaultValue(vm, prop.options)
105+
}
103106
vm[key] = vm._data[key] = assertProp(prop, value)
104107
? value
105108
: undefined
106109
}
107110

111+
/**
112+
* Get the default value of a prop.
113+
*
114+
* @param {Vue} vm
115+
* @param {Object} options
116+
* @return {*}
117+
*/
118+
119+
function getPropDefaultValue (vm, options) {
120+
// no default, return undefined
121+
if (!hasOwn(options, 'default')) {
122+
// absent boolean value defaults to false
123+
return options.type === Boolean
124+
? false
125+
: undefined
126+
}
127+
var def = options.default
128+
// warn against non-factory defaults for Object & Array
129+
if (isObject(def)) {
130+
process.env.NODE_ENV !== 'production' && warn(
131+
'Object/Array as default prop values will be shared ' +
132+
'across multiple instances. Use a factory function ' +
133+
'to return the default value instead.'
134+
)
135+
}
136+
// call factory function for non-Function types
137+
return typeof def === 'function' && options.type !== Function
138+
? def.call(vm)
139+
: def
140+
}
141+
108142
/**
109143
* Assert whether a prop is valid.
110144
*

test/unit/specs/directives/internal/prop_spec.js

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -681,4 +681,22 @@ describe('prop', function () {
681681
expect(hasWarned('did you mean `prop-b`')).toBe(true)
682682
expect(hasWarned('did you mean `prop-c`')).toBe(true)
683683
})
684+
685+
it('should use default for undefined values', function () {
686+
var vm = new Vue({
687+
el: el,
688+
template: '<comp :a="a"></comp>',
689+
components: {
690+
comp: {
691+
template: '{{a}}',
692+
props: {
693+
a: {
694+
default: 1
695+
}
696+
}
697+
}
698+
}
699+
})
700+
expect(vm.$el.textContent).toBe('1')
701+
})
684702
})

0 commit comments

Comments
 (0)