createApp,
provide,
inject,
- watch
+ watch,
+ toRefs
} from '@vue/runtime-test'
import { render as domRender, nextTick } from 'vue'
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)
+ })
})
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)
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