mirror of https://github.com/vuejs/core.git
fix(compiler-sfc): preserve old behavior when using withDefaults with desutructure
close #11930
This commit is contained in:
parent
fbae210d9d
commit
8492c3c49a
|
|
@ -378,14 +378,15 @@ describe('sfc reactive props destructure', () => {
|
||||||
).toThrow(`destructure cannot use computed key`)
|
).toThrow(`destructure cannot use computed key`)
|
||||||
})
|
})
|
||||||
|
|
||||||
test('should error when used with withDefaults', () => {
|
test('should warn when used with withDefaults', () => {
|
||||||
expect(() =>
|
compile(
|
||||||
compile(
|
`<script setup lang="ts">
|
||||||
`<script setup lang="ts">
|
const { foo } = withDefaults(defineProps<{ foo: string }>(), { foo: 'foo' })
|
||||||
const { foo } = withDefaults(defineProps<{ foo: string }>(), { foo: 'foo' })
|
</script>`,
|
||||||
</script>`,
|
)
|
||||||
),
|
expect(
|
||||||
).toThrow(`withDefaults() is unnecessary when using destructure`)
|
`withDefaults() is unnecessary when using destructure`,
|
||||||
|
).toHaveBeenWarned()
|
||||||
})
|
})
|
||||||
|
|
||||||
test('should error if destructure reference local vars', () => {
|
test('should error if destructure reference local vars', () => {
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ import type { ModelDecl } from './defineModel'
|
||||||
import type { BindingMetadata } from '../../../compiler-core/src'
|
import type { BindingMetadata } from '../../../compiler-core/src'
|
||||||
import MagicString from 'magic-string'
|
import MagicString from 'magic-string'
|
||||||
import type { TypeScope } from './resolveType'
|
import type { TypeScope } from './resolveType'
|
||||||
|
import { warn } from '../warn'
|
||||||
|
|
||||||
export class ScriptCompileContext {
|
export class ScriptCompileContext {
|
||||||
isJS: boolean
|
isJS: boolean
|
||||||
|
|
@ -145,20 +146,31 @@ export class ScriptCompileContext {
|
||||||
return block.content.slice(node.start!, node.end!)
|
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 {
|
error(msg: string, node: Node, scope?: TypeScope): never {
|
||||||
const offset = scope ? scope.offset : this.startOffset!
|
|
||||||
throw new Error(
|
throw new Error(
|
||||||
`[@vue/compiler-sfc] ${msg}\n\n${
|
`[@vue/compiler-sfc] ${generateError(msg, node, this, scope)}`,
|
||||||
(scope || this.descriptor).filename
|
|
||||||
}\n${generateCodeFrame(
|
|
||||||
(scope || this.descriptor).source,
|
|
||||||
node.start! + offset,
|
|
||||||
node.end! + offset,
|
|
||||||
)}`,
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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(
|
export function resolveParserPlugins(
|
||||||
lang: string,
|
lang: string,
|
||||||
userPlugins?: ParserPlugin[],
|
userPlugins?: ParserPlugin[],
|
||||||
|
|
|
||||||
|
|
@ -48,6 +48,7 @@ export function processDefineProps(
|
||||||
ctx: ScriptCompileContext,
|
ctx: ScriptCompileContext,
|
||||||
node: Node,
|
node: Node,
|
||||||
declId?: LVal,
|
declId?: LVal,
|
||||||
|
isWithDefaults = false,
|
||||||
): boolean {
|
): boolean {
|
||||||
if (!isCallOf(node, DEFINE_PROPS)) {
|
if (!isCallOf(node, DEFINE_PROPS)) {
|
||||||
return processWithDefaults(ctx, node, declId)
|
return processWithDefaults(ctx, node, declId)
|
||||||
|
|
@ -81,7 +82,7 @@ export function processDefineProps(
|
||||||
}
|
}
|
||||||
|
|
||||||
// handle props destructure
|
// handle props destructure
|
||||||
if (declId && declId.type === 'ObjectPattern') {
|
if (!isWithDefaults && declId && declId.type === 'ObjectPattern') {
|
||||||
processPropsDestructure(ctx, declId)
|
processPropsDestructure(ctx, declId)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -99,7 +100,14 @@ function processWithDefaults(
|
||||||
if (!isCallOf(node, WITH_DEFAULTS)) {
|
if (!isCallOf(node, WITH_DEFAULTS)) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
if (!processDefineProps(ctx, node.arguments[0], declId)) {
|
if (
|
||||||
|
!processDefineProps(
|
||||||
|
ctx,
|
||||||
|
node.arguments[0],
|
||||||
|
declId,
|
||||||
|
true /* isWithDefaults */,
|
||||||
|
)
|
||||||
|
) {
|
||||||
ctx.error(
|
ctx.error(
|
||||||
`${WITH_DEFAULTS}' first argument must be a ${DEFINE_PROPS} call.`,
|
`${WITH_DEFAULTS}' first argument must be a ${DEFINE_PROPS} call.`,
|
||||||
node.arguments[0] || node,
|
node.arguments[0] || node,
|
||||||
|
|
@ -113,10 +121,11 @@ function processWithDefaults(
|
||||||
node,
|
node,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
if (ctx.propsDestructureDecl) {
|
if (declId && declId.type === 'ObjectPattern') {
|
||||||
ctx.error(
|
ctx.warn(
|
||||||
`${WITH_DEFAULTS}() is unnecessary when using destructure with ${DEFINE_PROPS}().\n` +
|
`${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,
|
node.callee,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue