Skip to content

Commit

Permalink
fix(runtime-core): ensure declare prop keys are always present
Browse files Browse the repository at this point in the history
fix #3288
  • Loading branch information
yyx990803 committed Apr 2, 2021
1 parent f0cf14b commit 4fe4de0
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 2 deletions.
31 changes: 30 additions & 1 deletion packages/runtime-core/__tests__/componentProps.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ import {
createApp,
provide,
inject,
watch
watch,
toRefs
} from '@vue/runtime-test'
import { render as domRender, nextTick } from 'vue'

Expand Down Expand Up @@ -479,4 +480,32 @@ describe('component props', () => {
expect(serializeInner(root)).toMatch(`<h1>11</h1>`)
expect(count).toBe(0)
})

// #3288
test('declared prop key should be present even if not passed', async () => {
let initialKeys: string[] = []
const changeSpy = jest.fn()
const passFoo = ref(false)

const Comp = {
render() {},
props: {
foo: String
},
setup(props: any) {
initialKeys = Object.keys(props)
const { foo } = toRefs(props)
watch(foo, changeSpy)
}
}

const Parent = () => (passFoo.value ? h(Comp, { foo: 'ok' }) : h(Comp))
const root = nodeOps.createElement('div')
createApp(Parent).mount(root)

expect(initialKeys).toMatchObject(['foo'])
passFoo.value = true
await nextTick()
expect(changeSpy).toHaveBeenCalledTimes(1)
})
})
10 changes: 9 additions & 1 deletion packages/runtime-core/src/componentProps.ts
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,14 @@ export function initProps(
instance.propsDefaults = Object.create(null)

setFullProps(instance, rawProps, props, attrs)

// ensure all declared prop keys are present
for (const key in instance.propsOptions[0]) {
if (!(key in props)) {
props[key] = undefined
}
}

// validation
if (__DEV__) {
validateProps(rawProps || {}, props, instance)
Expand Down Expand Up @@ -281,11 +289,11 @@ function setFullProps(
const [options, needCastKeys] = instance.propsOptions
if (rawProps) {
for (const key in rawProps) {
const value = rawProps[key]
// key, ref are reserved and never passed down
if (isReservedProp(key)) {
continue
}
const value = rawProps[key]
// prop option names are camelized during normalization, so to support
// kebab -> camel conversion here we need to camelize the key.
let camelKey
Expand Down

0 comments on commit 4fe4de0

Please sign in to comment.