diff --git a/packages/compiler-sfc/__tests__/compileScript/definePropsDestructure.spec.ts b/packages/compiler-sfc/__tests__/compileScript/definePropsDestructure.spec.ts
index 6202f427b..106e469f1 100644
--- a/packages/compiler-sfc/__tests__/compileScript/definePropsDestructure.spec.ts
+++ b/packages/compiler-sfc/__tests__/compileScript/definePropsDestructure.spec.ts
@@ -378,14 +378,15 @@ describe('sfc reactive props destructure', () => {
).toThrow(`destructure cannot use computed key`)
})
- test('should error when used with withDefaults', () => {
- expect(() =>
- compile(
- ``,
- ),
- ).toThrow(`withDefaults() is unnecessary when using destructure`)
+ test('should warn when used with withDefaults', () => {
+ compile(
+ ``,
+ )
+ expect(
+ `withDefaults() is unnecessary when using destructure`,
+ ).toHaveBeenWarned()
})
test('should error if destructure reference local vars', () => {
diff --git a/packages/compiler-sfc/src/script/context.ts b/packages/compiler-sfc/src/script/context.ts
index 91ba0d748..47b6b442a 100644
--- a/packages/compiler-sfc/src/script/context.ts
+++ b/packages/compiler-sfc/src/script/context.ts
@@ -8,6 +8,7 @@ import type { ModelDecl } from './defineModel'
import type { BindingMetadata } from '../../../compiler-core/src'
import MagicString from 'magic-string'
import type { TypeScope } from './resolveType'
+import { warn } from '../warn'
export class ScriptCompileContext {
isJS: boolean
@@ -145,20 +146,31 @@ export class ScriptCompileContext {
return block.content.slice(node.start!, node.end!)
}
+ warn(msg: string, node: Node, scope?: TypeScope): void {
+ warn(generateError(msg, node, this, scope))
+ }
+
error(msg: string, node: Node, scope?: TypeScope): never {
- const offset = scope ? scope.offset : this.startOffset!
throw new Error(
- `[@vue/compiler-sfc] ${msg}\n\n${
- (scope || this.descriptor).filename
- }\n${generateCodeFrame(
- (scope || this.descriptor).source,
- node.start! + offset,
- node.end! + offset,
- )}`,
+ `[@vue/compiler-sfc] ${generateError(msg, node, this, scope)}`,
)
}
}
+function generateError(
+ msg: string,
+ node: Node,
+ ctx: ScriptCompileContext,
+ scope?: TypeScope,
+) {
+ const offset = scope ? scope.offset : ctx.startOffset!
+ return `${msg}\n\n${(scope || ctx.descriptor).filename}\n${generateCodeFrame(
+ (scope || ctx.descriptor).source,
+ node.start! + offset,
+ node.end! + offset,
+ )}`
+}
+
export function resolveParserPlugins(
lang: string,
userPlugins?: ParserPlugin[],
diff --git a/packages/compiler-sfc/src/script/defineProps.ts b/packages/compiler-sfc/src/script/defineProps.ts
index 6e2032c41..9a4880a1a 100644
--- a/packages/compiler-sfc/src/script/defineProps.ts
+++ b/packages/compiler-sfc/src/script/defineProps.ts
@@ -48,6 +48,7 @@ export function processDefineProps(
ctx: ScriptCompileContext,
node: Node,
declId?: LVal,
+ isWithDefaults = false,
): boolean {
if (!isCallOf(node, DEFINE_PROPS)) {
return processWithDefaults(ctx, node, declId)
@@ -81,7 +82,7 @@ export function processDefineProps(
}
// handle props destructure
- if (declId && declId.type === 'ObjectPattern') {
+ if (!isWithDefaults && declId && declId.type === 'ObjectPattern') {
processPropsDestructure(ctx, declId)
}
@@ -99,7 +100,14 @@ function processWithDefaults(
if (!isCallOf(node, WITH_DEFAULTS)) {
return false
}
- if (!processDefineProps(ctx, node.arguments[0], declId)) {
+ if (
+ !processDefineProps(
+ ctx,
+ node.arguments[0],
+ declId,
+ true /* isWithDefaults */,
+ )
+ ) {
ctx.error(
`${WITH_DEFAULTS}' first argument must be a ${DEFINE_PROPS} call.`,
node.arguments[0] || node,
@@ -113,10 +121,11 @@ function processWithDefaults(
node,
)
}
- if (ctx.propsDestructureDecl) {
- ctx.error(
+ if (declId && declId.type === 'ObjectPattern') {
+ ctx.warn(
`${WITH_DEFAULTS}() is unnecessary when using destructure with ${DEFINE_PROPS}().\n` +
- `Prefer using destructure default values, e.g. const { foo = 1 } = defineProps(...).`,
+ `Reactive destructure will be disabled when using withDefaults().\n` +
+ `Prefer using destructure default values, e.g. const { foo = 1 } = defineProps(...). `,
node.callee,
)
}