Skip to content
3 changes: 2 additions & 1 deletion packages/compiler-core/src/errors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ export enum ErrorCodes {
X_V_MODEL_ON_PROPS,
X_INVALID_EXPRESSION,
X_KEEP_ALIVE_INVALID_CHILDREN,

X_DEFINE_MODEL_NO_ASSIGNMENT,
// generic errors
X_PREFIX_ID_NOT_SUPPORTED,
X_MODULE_MODE_NOT_SUPPORTED,
Expand Down Expand Up @@ -179,6 +179,7 @@ export const errorMessages: Record<ErrorCodes, string> = {
[ErrorCodes.X_INVALID_EXPRESSION]: `Error parsing JavaScript expression: `,
[ErrorCodes.X_KEEP_ALIVE_INVALID_CHILDREN]: `<KeepAlive> expects exactly one child component.`,
[ErrorCodes.X_VNODE_HOOKS]: `@vnode-* hooks in templates are no longer supported. Use the vue: prefix instead. For example, @vnode-mounted should be changed to @vue:mounted. @vnode-* hooks support has been removed in 3.4.`,
[ErrorCodes.X_DEFINE_MODEL_NO_ASSIGNMENT]: `defineModel() must be assigned to a variable. For example: const model = defineModel()`,

// generic errors
[ErrorCodes.X_PREFIX_ID_NOT_SUPPORTED]: `"prefixIdentifiers" option is not supported in this build of compiler.`,
Expand Down
2 changes: 1 addition & 1 deletion packages/compiler-dom/src/errors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export function createDOMCompilerError(
}

export enum DOMErrorCodes {
X_V_HTML_NO_EXPRESSION = 53 /* ErrorCodes.__EXTEND_POINT__ */,
X_V_HTML_NO_EXPRESSION = 54 /* ErrorCodes.__EXTEND_POINT__ */,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Breaking change here

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should I update anything here?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just revert it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done. 😁

X_V_HTML_WITH_CHILDREN,
X_V_TEXT_NO_EXPRESSION,
X_V_TEXT_WITH_CHILDREN,
Expand Down
6 changes: 3 additions & 3 deletions packages/compiler-sfc/__tests__/compileScript.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -980,7 +980,7 @@ describe('SFC compile <script setup>', () => {
expect(() =>
compile(`<script setup>
let bar = 1
defineModel({
const model =defineModel({
default: () => bar
})
</script>`),
Expand All @@ -990,7 +990,7 @@ describe('SFC compile <script setup>', () => {
expect(() =>
compile(`<script setup>
const bar = 1
defineModel({
const model = defineModel({
default: () => bar
})
</script>`),
Expand All @@ -1000,7 +1000,7 @@ describe('SFC compile <script setup>', () => {
expect(() =>
compile(`<script setup>
let bar = 1
defineModel({
const model = defineModel({
get: () => bar,
set: () => bar
})
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { BindingTypes } from '@vue/compiler-core'
import { BindingTypes, ErrorCodes, errorMessages } from '@vue/compiler-core'
import { assertCode, compileSFCScript as compile } from '../utils'

describe('defineModel()', () => {
Expand Down Expand Up @@ -269,4 +269,14 @@ describe('defineModel()', () => {
modelValue: BindingTypes.SETUP_REF,
})
})

test('error when defineModel is not assigned to a variable', () => {
expect(() =>
compile(`
<script setup>
defineModel()
</script>
`),
).toThrow(errorMessages[ErrorCodes.X_DEFINE_MODEL_NO_ASSIGNMENT])
})
})
11 changes: 10 additions & 1 deletion packages/compiler-sfc/src/script/defineModel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,12 @@ import type { LVal, Node, TSType } from '@babel/types'
import type { ScriptCompileContext } from './context'
import { inferRuntimeType } from './resolveType'
import { UNKNOWN_TYPE, isCallOf, toRuntimeTypeString } from './utils'
import { BindingTypes, unwrapTSNode } from '@vue/compiler-dom'
import {
BindingTypes,
ErrorCodes,
errorMessages,
unwrapTSNode,
} from '@vue/compiler-dom'

export const DEFINE_MODEL = 'defineModel'

Expand All @@ -22,6 +27,10 @@ export function processDefineModel(
return false
}

if (!declId) {
ctx.error(errorMessages[ErrorCodes.X_DEFINE_MODEL_NO_ASSIGNMENT], node)
}

ctx.hasDefineModelCall = true

const type =
Expand Down