Skip to content

Commit 001184e

Browse files
committedNov 10, 2022
fix(compiler/v-model): catch incorrect v-model usage on prop bindings
close #5584
1 parent ec795bf commit 001184e

File tree

3 files changed

+31
-1
lines changed

3 files changed

+31
-1
lines changed
 

‎packages/compiler-core/__tests__/transforms/vModel.spec.ts

+19-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@ import {
1010
ComponentNode,
1111
NodeTypes,
1212
VNodeCall,
13-
NORMALIZE_PROPS
13+
NORMALIZE_PROPS,
14+
BindingTypes
1415
} from '../../src'
1516
import { ErrorCodes } from '../../src/errors'
1617
import { transformModel } from '../../src/transforms/vModel'
@@ -561,5 +562,22 @@ describe('compiler: transform v-model', () => {
561562
})
562563
)
563564
})
565+
566+
test('used on props', () => {
567+
const onError = jest.fn()
568+
parseWithVModel('<div v-model="p" />', {
569+
onError,
570+
bindingMetadata: {
571+
p: BindingTypes.PROPS
572+
}
573+
})
574+
575+
expect(onError).toHaveBeenCalledTimes(1)
576+
expect(onError).toHaveBeenCalledWith(
577+
expect.objectContaining({
578+
code: ErrorCodes.X_V_MODEL_ON_SCOPE_VARIABLE
579+
})
580+
)
581+
})
564582
})
565583
})

‎packages/compiler-core/src/errors.ts

+2
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ export const enum ErrorCodes {
8787
X_V_MODEL_NO_EXPRESSION,
8888
X_V_MODEL_MALFORMED_EXPRESSION,
8989
X_V_MODEL_ON_SCOPE_VARIABLE,
90+
X_V_MODEL_ON_PROPS,
9091
X_INVALID_EXPRESSION,
9192
X_KEEP_ALIVE_INVALID_CHILDREN,
9293

@@ -168,6 +169,7 @@ export const errorMessages: Record<ErrorCodes, string> = {
168169
[ErrorCodes.X_V_MODEL_NO_EXPRESSION]: `v-model is missing expression.`,
169170
[ErrorCodes.X_V_MODEL_MALFORMED_EXPRESSION]: `v-model value must be a valid JavaScript member expression.`,
170171
[ErrorCodes.X_V_MODEL_ON_SCOPE_VARIABLE]: `v-model cannot be used on v-for or v-slot scope variables because they are not writable.`,
172+
[ErrorCodes.X_V_MODEL_ON_PROPS]: `v-model cannot be used on a prop, because local prop bindings are not writable.\nUse a v-bind binding combined with a v-on listener that emits update:x event instead.`,
171173
[ErrorCodes.X_INVALID_EXPRESSION]: `Error parsing JavaScript expression: `,
172174
[ErrorCodes.X_KEEP_ALIVE_INVALID_CHILDREN]: `<KeepAlive> expects exactly one child component.`,
173175

‎packages/compiler-core/src/transforms/vModel.ts

+10
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,16 @@ export const transformModel: DirectiveTransform = (dir, node, context) => {
3535
// im SFC <script setup> inline mode, the exp may have been transformed into
3636
// _unref(exp)
3737
const bindingType = context.bindingMetadata[rawExp]
38+
39+
// check props
40+
if (
41+
bindingType === BindingTypes.PROPS ||
42+
bindingType === BindingTypes.PROPS_ALIASED
43+
) {
44+
context.onError(createCompilerError(ErrorCodes.X_V_MODEL_ON_PROPS, exp.loc))
45+
return createTransformProps()
46+
}
47+
3848
const maybeRef =
3949
!__BROWSER__ &&
4050
context.inline &&

0 commit comments

Comments
 (0)
Please sign in to comment.