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 (
|
} else if (
|
||||||
node.type === 'ObjectProperty' &&
|
node.type === 'ObjectProperty' &&
|
||||||
parent!.type === 'ObjectPattern'
|
parent?.type === 'ObjectPattern'
|
||||||
) {
|
) {
|
||||||
// mark property in destructure pattern
|
// mark property in destructure pattern
|
||||||
;(node as any).inPattern = true
|
;(node as any).inPattern = true
|
||||||
|
|
|
@ -953,6 +953,38 @@ describe('SFC compile <script setup>', () => {
|
||||||
</script>`).content,
|
</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.propsDestructureDecl, DEFINE_PROPS)
|
||||||
checkInvalidScopeReference(ctx.emitsRuntimeDecl, DEFINE_EMITS)
|
checkInvalidScopeReference(ctx.emitsRuntimeDecl, DEFINE_EMITS)
|
||||||
checkInvalidScopeReference(ctx.optionsRuntimeDecl, DEFINE_OPTIONS)
|
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
|
// 5. remove non-script content
|
||||||
if (script) {
|
if (script) {
|
||||||
|
|
|
@ -15,6 +15,7 @@ export interface ModelDecl {
|
||||||
type: TSType | undefined
|
type: TSType | undefined
|
||||||
options: string | undefined
|
options: string | undefined
|
||||||
identifier: string | undefined
|
identifier: string | undefined
|
||||||
|
runtimeOptionNodes: Node[]
|
||||||
}
|
}
|
||||||
|
|
||||||
export function processDefineModel(
|
export function processDefineModel(
|
||||||
|
@ -48,6 +49,7 @@ export function processDefineModel(
|
||||||
|
|
||||||
let optionsString = options && ctx.getString(options)
|
let optionsString = options && ctx.getString(options)
|
||||||
let optionsRemoved = !options
|
let optionsRemoved = !options
|
||||||
|
const runtimeOptionNodes: Node[] = []
|
||||||
|
|
||||||
if (
|
if (
|
||||||
options &&
|
options &&
|
||||||
|
@ -75,6 +77,8 @@ export function processDefineModel(
|
||||||
// remove prop options from runtime options
|
// remove prop options from runtime options
|
||||||
removed++
|
removed++
|
||||||
ctx.s.remove(ctx.startOffset! + start, ctx.startOffset! + end)
|
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) {
|
if (removed === options.properties.length) {
|
||||||
|
@ -89,6 +93,7 @@ export function processDefineModel(
|
||||||
ctx.modelDecls[modelName] = {
|
ctx.modelDecls[modelName] = {
|
||||||
type,
|
type,
|
||||||
options: optionsString,
|
options: optionsString,
|
||||||
|
runtimeOptionNodes,
|
||||||
identifier:
|
identifier:
|
||||||
declId && declId.type === 'Identifier' ? declId.name : undefined,
|
declId && declId.type === 'Identifier' ? declId.name : undefined,
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue