mirror of https://github.com/vuejs/core.git
fix(compiler/v-model): catch incorrect v-model usage on prop bindings
close #5584
This commit is contained in:
parent
ec795bfc51
commit
001184e6bb
|
@ -10,7 +10,8 @@ import {
|
|||
ComponentNode,
|
||||
NodeTypes,
|
||||
VNodeCall,
|
||||
NORMALIZE_PROPS
|
||||
NORMALIZE_PROPS,
|
||||
BindingTypes
|
||||
} from '../../src'
|
||||
import { ErrorCodes } from '../../src/errors'
|
||||
import { transformModel } from '../../src/transforms/vModel'
|
||||
|
@ -561,5 +562,22 @@ describe('compiler: transform v-model', () => {
|
|||
})
|
||||
)
|
||||
})
|
||||
|
||||
test('used on props', () => {
|
||||
const onError = jest.fn()
|
||||
parseWithVModel('<div v-model="p" />', {
|
||||
onError,
|
||||
bindingMetadata: {
|
||||
p: BindingTypes.PROPS
|
||||
}
|
||||
})
|
||||
|
||||
expect(onError).toHaveBeenCalledTimes(1)
|
||||
expect(onError).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
code: ErrorCodes.X_V_MODEL_ON_SCOPE_VARIABLE
|
||||
})
|
||||
)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
|
@ -87,6 +87,7 @@ export const enum ErrorCodes {
|
|||
X_V_MODEL_NO_EXPRESSION,
|
||||
X_V_MODEL_MALFORMED_EXPRESSION,
|
||||
X_V_MODEL_ON_SCOPE_VARIABLE,
|
||||
X_V_MODEL_ON_PROPS,
|
||||
X_INVALID_EXPRESSION,
|
||||
X_KEEP_ALIVE_INVALID_CHILDREN,
|
||||
|
||||
|
@ -168,6 +169,7 @@ export const errorMessages: Record<ErrorCodes, string> = {
|
|||
[ErrorCodes.X_V_MODEL_NO_EXPRESSION]: `v-model is missing expression.`,
|
||||
[ErrorCodes.X_V_MODEL_MALFORMED_EXPRESSION]: `v-model value must be a valid JavaScript member expression.`,
|
||||
[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.`,
|
||||
[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.`,
|
||||
[ErrorCodes.X_INVALID_EXPRESSION]: `Error parsing JavaScript expression: `,
|
||||
[ErrorCodes.X_KEEP_ALIVE_INVALID_CHILDREN]: `<KeepAlive> expects exactly one child component.`,
|
||||
|
||||
|
|
|
@ -35,6 +35,16 @@ export const transformModel: DirectiveTransform = (dir, node, context) => {
|
|||
// im SFC <script setup> inline mode, the exp may have been transformed into
|
||||
// _unref(exp)
|
||||
const bindingType = context.bindingMetadata[rawExp]
|
||||
|
||||
// check props
|
||||
if (
|
||||
bindingType === BindingTypes.PROPS ||
|
||||
bindingType === BindingTypes.PROPS_ALIASED
|
||||
) {
|
||||
context.onError(createCompilerError(ErrorCodes.X_V_MODEL_ON_PROPS, exp.loc))
|
||||
return createTransformProps()
|
||||
}
|
||||
|
||||
const maybeRef =
|
||||
!__BROWSER__ &&
|
||||
context.inline &&
|
||||
|
|
Loading…
Reference in New Issue