diff --git a/packages/compiler-sfc/__tests__/compileScript/__snapshots__/defineProps.spec.ts.snap b/packages/compiler-sfc/__tests__/compileScript/__snapshots__/defineProps.spec.ts.snap
index 62d9bef5d27..e90d6303bab 100644
--- a/packages/compiler-sfc/__tests__/compileScript/__snapshots__/defineProps.spec.ts.snap
+++ b/packages/compiler-sfc/__tests__/compileScript/__snapshots__/defineProps.spec.ts.snap
@@ -338,6 +338,27 @@ return { props, get defaults() { return defaults } }
})"
`;
+exports[`defineProps > withDefaults (locally variable) 1`] = `
+"import { mergeDefaults as _mergeDefaults, defineComponent as _defineComponent } from 'vue'
+const defaults = { baz: false }
+
+export default /*#__PURE__*/_defineComponent({
+ props: _mergeDefaults({
+ baz: { type: Boolean, required: true }
+ }, defaults),
+ setup(__props: any, { expose: __expose }) {
+ __expose();
+
+const props = __props;
+
+
+
+return { defaults, props }
+}
+
+})"
+`;
+
exports[`defineProps > withDefaults (reference) 1`] = `
"import { mergeDefaults as _mergeDefaults, defineComponent as _defineComponent } from 'vue'
import { defaults } from './foo'
diff --git a/packages/compiler-sfc/__tests__/compileScript/defineProps.spec.ts b/packages/compiler-sfc/__tests__/compileScript/defineProps.spec.ts
index 43f54b0aa1e..4d2d417d3fb 100644
--- a/packages/compiler-sfc/__tests__/compileScript/defineProps.spec.ts
+++ b/packages/compiler-sfc/__tests__/compileScript/defineProps.spec.ts
@@ -470,6 +470,26 @@ const props = defineProps({ foo: String })
)
})
+ test('withDefaults (locally variable)', () => {
+ const { content } = compile(`
+
+ `)
+
+ assertCode(content)
+ expect(content).toMatch(`import { mergeDefaults as _mergeDefaults`)
+ expect(content).toMatch(
+ `
+ _mergeDefaults({
+ baz: { type: Boolean, required: true }
+ }, defaults)`.trim()
+ )
+ })
+
// #7111
test('withDefaults (dynamic) w/ production mode', () => {
const { content } = compile(
@@ -607,5 +627,19 @@ const props = defineProps({ foo: String })
`)
}).toThrow(`cannot accept both type and non-type arguments`)
})
+
+ test('withDefaults (locally variable)', () => {
+ expect(() => {
+ compile(`
+
+ `)
+ }).toThrow(`cannot reference locally declared variables`)
+ })
})
})
diff --git a/packages/compiler-sfc/src/compileScript.ts b/packages/compiler-sfc/src/compileScript.ts
index 046797cfbe5..66acc4cbcf9 100644
--- a/packages/compiler-sfc/src/compileScript.ts
+++ b/packages/compiler-sfc/src/compileScript.ts
@@ -193,6 +193,13 @@ export function compileScript(
// const ctx.bindingMetadata: BindingMetadata = {}
const scriptBindings: Record = Object.create(null)
const setupBindings: Record = Object.create(null)
+ const withDefaultsVariables: Record<
+ string,
+ {
+ node: Statement
+ needHoist?: boolean
+ }
+ > = {}
let defaultExport: Node | undefined
let hasAwait = false
@@ -258,7 +265,11 @@ export function compileScript(
if (!node) return
walkIdentifiers(node, id => {
const binding = setupBindings[id.name]
- if (binding && binding !== BindingTypes.LITERAL_CONST) {
+ if (
+ binding &&
+ binding !== BindingTypes.LITERAL_CONST &&
+ !withDefaultsVariables[id.name].needHoist
+ ) {
ctx.error(
`\`${method}()\` in