mirror of https://github.com/vuejs/core.git
dx(defineModel): warn against reference of setup scope variables in defineModel options
close #10093
This commit is contained in:
parent
d35b87725a
commit
c60479146a
|
@ -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
|
||||
|
|
|
@ -953,6 +953,38 @@ describe('SFC compile <script setup>', () => {
|
|||
</script>`).content,
|
||||
)
|
||||
})
|
||||
|
||||
test('defineModel() referencing local var', () => {
|
||||
expect(() =>
|
||||
compile(`<script setup>
|
||||
let bar = 1
|
||||
defineModel({
|
||||
default: () => bar
|
||||
})
|
||||
</script>`),
|
||||
).toThrow(`cannot reference locally declared variables`)
|
||||
|
||||
// allow const
|
||||
expect(() =>
|
||||
compile(`<script setup>
|
||||
const bar = 1
|
||||
defineModel({
|
||||
default: () => bar
|
||||
})
|
||||
</script>`),
|
||||
).not.toThrow(`cannot reference locally declared variables`)
|
||||
|
||||
// allow in get/set
|
||||
expect(() =>
|
||||
compile(`<script setup>
|
||||
let bar = 1
|
||||
defineModel({
|
||||
get: () => bar,
|
||||
set: () => bar
|
||||
})
|
||||
</script>`),
|
||||
).not.toThrow(`cannot reference locally declared variables`)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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,
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue