diff --git a/src/core/util/options.ts b/src/core/util/options.ts index e9b7c489e1..baddeb09b6 100644 --- a/src/core/util/options.ts +++ b/src/core/util/options.ts @@ -467,7 +467,7 @@ export function resolveAsset( // fallback to prototype chain const res = assets[id] || assets[camelizedId] || assets[PascalCaseId] if (__DEV__ && warnMissing && !res) { - warn('Failed to resolve ' + type.slice(0, -1) + ': ' + id, options) + warn('Failed to resolve ' + type.slice(0, -1) + ': ' + id) } return res } diff --git a/src/types/options.ts b/src/types/options.ts index b5626acb25..27b3d7afc3 100644 --- a/src/types/options.ts +++ b/src/types/options.ts @@ -26,7 +26,9 @@ export type ComponentOptions = { // data data: object | Function | void - props?: { [key: string]: PropOptions } + props?: + | string[] + | Record | null | PropOptions> propsData?: object computed?: { [key: string]: @@ -105,8 +107,8 @@ export type ComponentOptions = { } export type PropOptions = { - type: Function | Array | null - default: any - required: boolean | null - validator: Function | null + type?: Function | Array | null + default?: any + required?: boolean | null + validator?: Function | null } diff --git a/src/v3/apiSetup.ts b/src/v3/apiSetup.ts index e4cadb1067..811453b996 100644 --- a/src/v3/apiSetup.ts +++ b/src/v3/apiSetup.ts @@ -1,7 +1,14 @@ import { Component } from 'types/component' +import { PropOptions } from 'types/options' import { def, invokeWithErrorHandling, isReserved, warn } from '../core/util' import VNode from '../core/vdom/vnode' -import { bind, emptyObject, isFunction, isObject } from '../shared/util' +import { + bind, + emptyObject, + isArray, + isFunction, + isObject +} from '../shared/util' import { currentInstance, setCurrentInstance } from './currentInstance' import { isRef } from './reactivity/ref' @@ -193,3 +200,35 @@ function getContext(): SetupContext { const vm = currentInstance! return vm._setupContext || (vm._setupContext = createSetupContext(vm)) } + +/** + * Runtime helper for merging default declarations. Imported by compiled code + * only. + * @internal + */ +export function mergeDefaults( + raw: string[] | Record, + defaults: Record +): Record { + const props = isArray(raw) + ? raw.reduce( + (normalized, p) => ((normalized[p] = {}), normalized), + {} as Record + ) + : raw + for (const key in defaults) { + const opt = props[key] + if (opt) { + if (isArray(opt) || isFunction(opt)) { + props[key] = { type: opt, default: defaults[key] } + } else { + opt.default = defaults[key] + } + } else if (opt === null) { + props[key] = { default: defaults[key] } + } else if (__DEV__) { + warn(`props default key "${key}" has no corresponding declaration.`) + } + } + return props +} diff --git a/src/v3/apiWatch.ts b/src/v3/apiWatch.ts index 67aafc5fd1..909bd0258e 100644 --- a/src/v3/apiWatch.ts +++ b/src/v3/apiWatch.ts @@ -179,10 +179,8 @@ function doWatch( const warnInvalidSource = (s: unknown) => { warn( - `Invalid watch source: `, - s, - `A watch source can only be a getter/effect function, a ref, ` + - `a reactive object, or an array of these types.` + `Invalid watch source: ${s}. A watch source can only be a getter/effect ` + + `function, a ref, a reactive object, or an array of these types.` ) } diff --git a/src/v3/index.ts b/src/v3/index.ts index 2e6a71c5bf..7a9779eedb 100644 --- a/src/v3/index.ts +++ b/src/v3/index.ts @@ -70,7 +70,7 @@ export { provide, inject, InjectionKey } from './apiInject' export { h } from './h' export { getCurrentInstance } from './currentInstance' -export { useSlots, useAttrs } from './apiSetup' +export { useSlots, useAttrs, mergeDefaults } from './apiSetup' export { nextTick } from 'core/util/next-tick' export { set, del } from 'core/observer' diff --git a/types/index.d.ts b/types/index.d.ts index d8722c3b8d..dd5aab503d 100644 --- a/types/index.d.ts +++ b/types/index.d.ts @@ -35,6 +35,8 @@ export { export * from './v3-manual-apis' export * from './v3-generated' +//