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,
|
ComponentNode,
|
||||||
NodeTypes,
|
NodeTypes,
|
||||||
VNodeCall,
|
VNodeCall,
|
||||||
NORMALIZE_PROPS
|
NORMALIZE_PROPS,
|
||||||
|
BindingTypes
|
||||||
} from '../../src'
|
} from '../../src'
|
||||||
import { ErrorCodes } from '../../src/errors'
|
import { ErrorCodes } from '../../src/errors'
|
||||||
import { transformModel } from '../../src/transforms/vModel'
|
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_NO_EXPRESSION,
|
||||||
X_V_MODEL_MALFORMED_EXPRESSION,
|
X_V_MODEL_MALFORMED_EXPRESSION,
|
||||||
X_V_MODEL_ON_SCOPE_VARIABLE,
|
X_V_MODEL_ON_SCOPE_VARIABLE,
|
||||||
|
X_V_MODEL_ON_PROPS,
|
||||||
X_INVALID_EXPRESSION,
|
X_INVALID_EXPRESSION,
|
||||||
X_KEEP_ALIVE_INVALID_CHILDREN,
|
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_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_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_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_INVALID_EXPRESSION]: `Error parsing JavaScript expression: `,
|
||||||
[ErrorCodes.X_KEEP_ALIVE_INVALID_CHILDREN]: `<KeepAlive> expects exactly one child component.`,
|
[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
|
// im SFC <script setup> inline mode, the exp may have been transformed into
|
||||||
// _unref(exp)
|
// _unref(exp)
|
||||||
const bindingType = context.bindingMetadata[rawExp]
|
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 =
|
const maybeRef =
|
||||||
!__BROWSER__ &&
|
!__BROWSER__ &&
|
||||||
context.inline &&
|
context.inline &&
|
||||||
|
|
Loading…
Reference in New Issue