diff --git a/packages/compiler-core/src/babelUtils.ts b/packages/compiler-core/src/babelUtils.ts
index 0a7f48af9..b12a6d9b4 100644
--- a/packages/compiler-core/src/babelUtils.ts
+++ b/packages/compiler-core/src/babelUtils.ts
@@ -50,7 +50,7 @@ export function walkIdentifiers(
}
} else if (
node.type === 'ObjectProperty' &&
- parent!.type === 'ObjectPattern'
+ parent?.type === 'ObjectPattern'
) {
// mark property in destructure pattern
;(node as any).inPattern = true
diff --git a/packages/compiler-sfc/__tests__/compileScript.spec.ts b/packages/compiler-sfc/__tests__/compileScript.spec.ts
index 7c21816eb..2b9acbc7f 100644
--- a/packages/compiler-sfc/__tests__/compileScript.spec.ts
+++ b/packages/compiler-sfc/__tests__/compileScript.spec.ts
@@ -953,6 +953,38 @@ describe('SFC compile `).content,
)
})
+
+ test('defineModel() referencing local var', () => {
+ expect(() =>
+ compile(``),
+ ).toThrow(`cannot reference locally declared variables`)
+
+ // allow const
+ expect(() =>
+ compile(``),
+ ).not.toThrow(`cannot reference locally declared variables`)
+
+ // allow in get/set
+ expect(() =>
+ compile(``),
+ ).not.toThrow(`cannot reference locally declared variables`)
+ })
})
})
diff --git a/packages/compiler-sfc/src/compileScript.ts b/packages/compiler-sfc/src/compileScript.ts
index b0b79f8c8..69beb2af7 100644
--- a/packages/compiler-sfc/src/compileScript.ts
+++ b/packages/compiler-sfc/src/compileScript.ts
@@ -671,6 +671,11 @@ export function compileScript(
checkInvalidScopeReference(ctx.propsDestructureDecl, DEFINE_PROPS)
checkInvalidScopeReference(ctx.emitsRuntimeDecl, DEFINE_EMITS)
checkInvalidScopeReference(ctx.optionsRuntimeDecl, DEFINE_OPTIONS)
+ for (const { runtimeOptionNodes } of Object.values(ctx.modelDecls)) {
+ for (const node of runtimeOptionNodes) {
+ checkInvalidScopeReference(node, DEFINE_MODEL)
+ }
+ }
// 5. remove non-script content
if (script) {
diff --git a/packages/compiler-sfc/src/script/defineModel.ts b/packages/compiler-sfc/src/script/defineModel.ts
index b94b79946..24fd0780e 100644
--- a/packages/compiler-sfc/src/script/defineModel.ts
+++ b/packages/compiler-sfc/src/script/defineModel.ts
@@ -15,6 +15,7 @@ export interface ModelDecl {
type: TSType | undefined
options: string | undefined
identifier: string | undefined
+ runtimeOptionNodes: Node[]
}
export function processDefineModel(
@@ -48,6 +49,7 @@ export function processDefineModel(
let optionsString = options && ctx.getString(options)
let optionsRemoved = !options
+ const runtimeOptionNodes: Node[] = []
if (
options &&
@@ -75,6 +77,8 @@ export function processDefineModel(
// remove prop options from runtime options
removed++
ctx.s.remove(ctx.startOffset! + start, ctx.startOffset! + end)
+ // record prop options for invalid scope var reference check
+ runtimeOptionNodes.push(p)
}
}
if (removed === options.properties.length) {
@@ -89,6 +93,7 @@ export function processDefineModel(
ctx.modelDecls[modelName] = {
type,
options: optionsString,
+ runtimeOptionNodes,
identifier:
declId && declId.type === 'Identifier' ? declId.name : undefined,
}