Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 02655cd

Browse filesBrowse files
committed
props: adjust props merging strategy (fix vuejs#1431)
1 parent 9af9c29 commit 02655cd
Copy full SHA for 02655cd

File tree

5 files changed

+73
-49
lines changed
Filter options

5 files changed

+73
-49
lines changed

‎src/compiler/compile-props.js

Copy file name to clipboardExpand all lines: src/compiler/compile-props.js
+5-3Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ var _ = require('../util')
22
var dirParser = require('../parsers/directive')
33
var propDef = require('../directives/internal/prop')
44
var propBindingModes = require('../config')._propBindingModes
5+
var empty = {}
56

67
// regexes
78
var identRE = require('../parsers/path').identRE
@@ -18,11 +19,12 @@ var settablePathRE = /^[A-Za-z_$][\w$]*(\.[A-Za-z_$][\w$]*|\[[^\[\]]+\])*$/
1819

1920
module.exports = function compileProps (el, propOptions) {
2021
var props = []
21-
var i = propOptions.length
22+
var names = Object.keys(propOptions)
23+
var i = names.length
2224
var options, name, attr, value, path, parsed, prop
2325
while (i--) {
24-
options = propOptions[i]
25-
name = options.name
26+
name = names[i]
27+
options = propOptions[name] || empty
2628

2729
if (process.env.NODE_ENV !== 'production' && name === '$data') {
2830
_.warn('Do not use $data as prop.')

‎src/util/options.js

Copy file name to clipboardExpand all lines: src/util/options.js
+19-17Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -116,8 +116,7 @@ strats.detached =
116116
strats.beforeCompile =
117117
strats.compiled =
118118
strats.beforeDestroy =
119-
strats.destroyed =
120-
strats.props = function (parentVal, childVal) {
119+
strats.destroyed = function (parentVal, childVal) {
121120
return childVal
122121
? parentVal
123122
? parentVal.concat(childVal)
@@ -188,11 +187,13 @@ strats.events = function (parentVal, childVal) {
188187
* Other object hashes.
189188
*/
190189

190+
strats.props =
191191
strats.methods =
192192
strats.computed = function (parentVal, childVal) {
193193
if (!childVal) return parentVal
194194
if (!parentVal) return childVal
195-
var ret = Object.create(parentVal)
195+
var ret = Object.create(null)
196+
extend(ret, parentVal)
196197
extend(ret, childVal)
197198
return ret
198199
}
@@ -247,21 +248,22 @@ function guardComponents (options) {
247248

248249
function guardProps (options) {
249250
var props = options.props
250-
if (_.isPlainObject(props)) {
251-
options.props = Object.keys(props).map(function (key) {
252-
var val = props[key]
253-
if (!_.isPlainObject(val)) {
254-
val = { type: val }
251+
var i
252+
if (_.isArray(props)) {
253+
options.props = {}
254+
i = props.length
255+
while (i--) {
256+
options.props[props[i]] = null
257+
}
258+
} else if (_.isPlainObject(props)) {
259+
var keys = Object.keys(props)
260+
i = keys.length
261+
while (i--) {
262+
var val = props[keys[i]]
263+
if (typeof val === 'function') {
264+
props[keys[i]] = { type: val }
255265
}
256-
val.name = key
257-
return val
258-
})
259-
} else if (_.isArray(props)) {
260-
options.props = props.map(function (prop) {
261-
return typeof prop === 'string'
262-
? { name: prop }
263-
: prop
264-
})
266+
}
265267
}
266268
}
267269

‎test/unit/specs/compiler/compile_spec.js

Copy file name to clipboardExpand all lines: test/unit/specs/compiler/compile_spec.js
+9-12Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -239,14 +239,14 @@ if (_.inBrowser) {
239239

240240
it('props', function () {
241241
var bindingModes = Vue.config._propBindingModes
242-
var props = [
243-
{ name: 'testNormal' },
244-
{ name: 'testLiteral' },
245-
{ name: 'testTwoWay' },
246-
{ name: 'twoWayWarn' },
247-
{ name: 'testOneTime' },
248-
{ name: 'optimizeLiteral' }
249-
]
242+
var props = {
243+
testNormal: null,
244+
testLiteral: null,
245+
testTwoWay: null,
246+
twoWayWarn: null,
247+
testOneTime: null,
248+
optimizeLiteral: null
249+
}
250250
el.innerHTML = '<div ' +
251251
'v-bind:test-normal="a" ' +
252252
'test-literal="1" ' +
@@ -288,10 +288,7 @@ if (_.inBrowser) {
288288
vm._context = null
289289
el.setAttribute('v-bind:a', '"hi"')
290290
el.setAttribute(':b', 'hi')
291-
compiler.compileAndLinkProps(vm, el, [
292-
{ name: 'a' },
293-
{ name: 'b' }
294-
])
291+
compiler.compileAndLinkProps(vm, el, { a: null, b: null })
295292
expect(vm._bindDir.calls.count()).toBe(0)
296293
expect(vm._data.a).toBe('hi')
297294
expect(hasWarned(_, 'Cannot bind dynamic prop on a root')).toBe(true)

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

Copy file name to clipboardExpand all lines: test/unit/specs/directives/internal/prop_spec.js
+6-10Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -306,13 +306,12 @@ if (_.inBrowser) {
306306
},
307307
components: {
308308
test: {
309-
props: [
310-
{
311-
name: 'test',
309+
props: {
310+
test: {
312311
type: type,
313312
validator: validator
314313
}
315-
]
314+
}
316315
}
317316
}
318317
})
@@ -400,12 +399,9 @@ if (_.inBrowser) {
400399
template: '<test></test>',
401400
components: {
402401
test: {
403-
props: [
404-
{
405-
name: 'prop',
406-
required: true
407-
}
408-
]
402+
props: {
403+
prop: { required: true }
404+
}
409405
}
410406
}
411407
})

‎test/unit/specs/util/options_spec.js

Copy file name to clipboardExpand all lines: test/unit/specs/util/options_spec.js
+34-7Lines changed: 34 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ describe('Util - Option merging', function () {
1818
expect(res).toBe(false)
1919
})
2020

21-
it('hooks & props', function () {
21+
it('hooks', function () {
2222
var fn1 = function () {}
2323
var fn2 = function () {}
2424
var res
@@ -38,12 +38,6 @@ describe('Util - Option merging', function () {
3838
expect(res.length).toBe(2)
3939
expect(res[0]).toBe(fn1)
4040
expect(res[1]).toBe(fn2)
41-
// both arrays
42-
res = merge({props: [1]}, {props: [2]}).props
43-
expect(Array.isArray(res)).toBe(true)
44-
expect(res.length).toBe(2)
45-
expect(res[0]).toBe(1)
46-
expect(res[1]).toBe(2)
4741
})
4842

4943
it('events', function () {
@@ -114,6 +108,39 @@ describe('Util - Option merging', function () {
114108
expect(res.b).toBe(asset2)
115109
})
116110

111+
it('props', function () {
112+
var res = merge({
113+
props: {
114+
a: null,
115+
d: null
116+
}
117+
}, {
118+
props: {
119+
a: { required: true },
120+
b: Boolean,
121+
c: { type: Array }
122+
}
123+
})
124+
expect(typeof res.props.a).toBe('object')
125+
expect(res.props.a.required).toBe(true)
126+
expect(typeof res.props.b).toBe('object')
127+
expect(res.props.b.type).toBe(Boolean)
128+
expect(typeof res.props.c).toBe('object')
129+
expect(res.props.c.type).toBe(Array)
130+
expect(res.props.d).toBe(null)
131+
132+
// check array syntax
133+
res = merge({
134+
props: {
135+
b: null
136+
}
137+
}, {
138+
props: ['a']
139+
})
140+
expect(res.props.a).toBe(null)
141+
expect(res.props.b).toBe(null)
142+
})
143+
117144
it('guard components', function () {
118145
var res = merge({
119146
components: null

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.