From c80b857eb5b19f48f498147479a779af9953be32 Mon Sep 17 00:00:00 2001 From: Evan You Date: Tue, 14 Apr 2020 16:17:35 -0400 Subject: [PATCH] fix(runtime-core): should resolve value instead of delete for dynamic props with options --- .../__tests__/componentProps.spec.ts | 10 +++- packages/runtime-core/src/componentProps.ts | 48 +++++++++++-------- 2 files changed, 37 insertions(+), 21 deletions(-) diff --git a/packages/runtime-core/__tests__/componentProps.spec.ts b/packages/runtime-core/__tests__/componentProps.spec.ts index 402fc0d6..9e8299ff 100644 --- a/packages/runtime-core/__tests__/componentProps.spec.ts +++ b/packages/runtime-core/__tests__/componentProps.spec.ts @@ -175,9 +175,17 @@ describe('component props', () => { expect(proxy.foo).toBe(2) expect(proxy.bar).toEqual({ a: 1 }) - render(h(Comp, { foo: undefined, bar: { b: 2 } }), root) + render(h(Comp, { bar: { b: 2 } }), root) expect(proxy.foo).toBe(1) expect(proxy.bar).toEqual({ b: 2 }) + + render(h(Comp, { foo: 3, bar: { b: 3 } }), root) + expect(proxy.foo).toBe(3) + expect(proxy.bar).toEqual({ b: 3 }) + + render(h(Comp, { bar: { b: 4 } }), root) + expect(proxy.foo).toBe(1) + expect(proxy.bar).toEqual({ b: 4 }) }) test('optimized props updates', async () => { diff --git a/packages/runtime-core/src/componentProps.ts b/packages/runtime-core/src/componentProps.ts index 0ca0dbaa..5b871076 100644 --- a/packages/runtime-core/src/componentProps.ts +++ b/packages/runtime-core/src/componentProps.ts @@ -186,7 +186,16 @@ export function updateProps( // and converted to camelCase (#955) ((kebabKey = hyphenate(key)) === key || !hasOwn(rawProps, kebabKey))) ) { - delete props[key] + if (options) { + props[key] = resolvePropValue( + options, + rawProps || EMPTY_OBJ, + key, + undefined + ) + } else { + delete props[key] + } } } for (const key in attrs) { @@ -250,25 +259,24 @@ function resolvePropValue( key: string, value: unknown ) { - let opt = options[key] - if (opt == null) { - return value - } - const hasDefault = hasOwn(opt, 'default') - // default values - if (hasDefault && value === undefined) { - const defaultValue = opt.default - value = isFunction(defaultValue) ? defaultValue() : defaultValue - } - // boolean casting - if (opt[BooleanFlags.shouldCast]) { - if (!hasOwn(props, key) && !hasDefault) { - value = false - } else if ( - opt[BooleanFlags.shouldCastTrue] && - (value === '' || value === hyphenate(key)) - ) { - value = true + const opt = options[key] + if (opt != null) { + const hasDefault = hasOwn(opt, 'default') + // default values + if (hasDefault && value === undefined) { + const defaultValue = opt.default + value = isFunction(defaultValue) ? defaultValue() : defaultValue + } + // boolean casting + if (opt[BooleanFlags.shouldCast]) { + if (!hasOwn(props, key) && !hasDefault) { + value = false + } else if ( + opt[BooleanFlags.shouldCastTrue] && + (value === '' || value === hyphenate(key)) + ) { + value = true + } } } return value